Bug Summary

File:/home/sdobbs/work/clang/halld_recon/src/libraries/HDGEOMETRY/DGeometry.cc
Warning:line 2093, column 24
The left operand of '+' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -main-file-name DGeometry.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0 -D HAVE_CCDB -D HAVE_RCDB -D HAVE_EVIO -D HAVE_TMVA=1 -D RCDB_MYSQL=1 -D RCDB_SQLITE=1 -D SQLITE_USE_LEGACY_STRUCT=ON -I .Linux_CentOS7.7-x86_64-gcc4.8.5/libraries/HDGEOMETRY -I libraries/HDGEOMETRY -I . -I libraries -I libraries/include -I /w/halld-scifs17exp/home/sdobbs/clang/halld_recon/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I external/xstream/include -I /usr/include/tirpc -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/root/root-6.08.06/include -I /w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/ccdb/ccdb_1.06.06/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/rcdb/rcdb_0.06.00/cpp/include -I /usr/include/mysql -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlitecpp/SQLiteCpp-2.2.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlite/sqlite-3.13.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/hdds/hdds-4.9.0/Linux_CentOS7.7-x86_64-gcc4.8.5/src -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/xerces-c/xerces-c-3.1.4/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/evio/evio-4.4.6/Linux-x86_64/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/backward -internal-isystem /usr/local/include -internal-isystem /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /home/sdobbs/work/clang/halld_recon/src -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-01-21-110224-160369-1 -x c++ libraries/HDGEOMETRY/DGeometry.cc

libraries/HDGEOMETRY/DGeometry.cc

1// $Id$
2//
3// File: DGeometry.cc
4// Created: Thu Apr 3 08:43:06 EDT 2008
5// Creator: davidl (on Darwin swire-d95.jlab.org 8.11.1 i386)
6//
7
8#include <algorithm>
9using namespace std;
10
11#include "DGeometry.h"
12#include <JANA/JGeometryXML.h>
13#include "FDC/DFDCWire.h"
14#include "FDC/DFDCGeometry.h"
15#include <ansi_escape((char)0x1b).h>
16
17using namespace std;
18
19#ifndef M_TWO_PI6.28318530717958647692
20#define M_TWO_PI6.28318530717958647692 6.28318530717958647692
21#endif
22
23//---------------------------------
24// DGeometry (Constructor)
25//---------------------------------
26DGeometry::DGeometry(JGeometry *jgeom, DApplication *dapp, int32_t runnumber)
27{
28 this->jgeom = jgeom;
29 this->dapp = dapp;
30 this->bfield = NULL__null; // don't ask for B-field object before we're asked for it
31 this->runnumber = runnumber;
32 this->materialmaps_read = false;
33 this->materials_read = false;
34
35 pthread_mutex_init(&bfield_mutex, NULL__null);
36 pthread_mutex_init(&materialmap_mutex, NULL__null);
37 pthread_mutex_init(&materials_mutex, NULL__null);
38
39 ReadMaterialMaps();
40}
41
42//---------------------------------
43// ~DGeometry (Destructor)
44//---------------------------------
45DGeometry::~DGeometry()
46{
47 pthread_mutex_lock(&materials_mutex);
48 for(unsigned int i=0; i<materials.size(); i++)delete materials[i];
49 materials.clear();
50 pthread_mutex_unlock(&materials_mutex);
51
52 pthread_mutex_lock(&materialmap_mutex);
53 for(unsigned int i=0; i<materialmaps.size(); i++)delete materialmaps[i];
54 materialmaps.clear();
55 pthread_mutex_unlock(&materialmap_mutex);
56}
57
58//---------------------------------
59// GetBfield
60//---------------------------------
61DMagneticFieldMap* DGeometry::GetBfield(void) const
62{
63 pthread_mutex_lock(&bfield_mutex);
64 if(bfield == NULL__null) bfield = dapp->GetBfield(runnumber);
65 pthread_mutex_unlock(&bfield_mutex);
66
67 return bfield;
68}
69
70//---------------------------------
71// GetLorentzDeflections
72//---------------------------------
73DLorentzDeflections* DGeometry::GetLorentzDeflections(void)
74{
75 return dapp->GetLorentzDeflections(runnumber);
76}
77
78//---------------------------------
79// GetMaterialMapVector
80//---------------------------------
81vector<DMaterialMap*> DGeometry::GetMaterialMapVector(void) const
82{
83// ReadMaterialMaps();
84
85 return materialmaps;
86}
87
88//---------------------------------
89// ReadMaterialMaps
90//---------------------------------
91void DGeometry::ReadMaterialMaps(void) const
92{
93 /// This gets called by several "FindMat" methods below. It
94 /// will return immediately if the material maps have already
95 /// been read in. If they have not been read in, then it reads
96 /// them and sets a flag so that they are only read in once.
97 ///
98 /// Orginally, this code resided in the constructor, but was
99 /// moved here so that programs not requiring the material
100 /// maps could start up quicker and skip reading them in altogether.
101
102 // Lock mutex so we can check flag to see if maps have already
103 // been read in
104 pthread_mutex_lock(&materialmap_mutex);
105 if(materialmaps_read){
106 // Maps are already read. Unlock mutex and return now
107 pthread_mutex_unlock(&materialmap_mutex);
108 return;
109 }
110
111 JCalibration * jcalib = dapp->GetJCalibration(runnumber);
112 if(!jcalib){
113 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<113<<" "
<<"ERROR: Unable to get JCalibration object!"<<endl;
114 pthread_mutex_unlock(&materialmap_mutex);
115 return;
116 }
117
118 // Get a list of all namepaths so we can find all of the material maps.
119 // We want to read in all material maps with a standard naming scheme
120 // so the number and coverage of the piece-wise maps can be changed
121 // without requiring recompilation.
122 //vector<DMaterialMap*> material_maps;
123 vector<string> namepaths;
124 jcalib->GetListOfNamepaths(namepaths);
125 vector<string> material_namepaths;
126 for(unsigned int i=0; i<namepaths.size(); i++){
127 if(namepaths[i].find("Material/material_map")==0)material_namepaths.push_back(namepaths[i]);
128 }
129
130 // Sort alphabetically so user controls search sequence by map name
131 sort(material_namepaths.begin(), material_namepaths.end());
132
133 // Inform user what's happening
134 if(material_namepaths.size()==0){
135 jerr<<"No material maps found in calibration DB!!"<<endl;
136 pthread_mutex_unlock(&materialmap_mutex);
137 return;
138 }
139 jout<<"Found "<<material_namepaths.size()<<" material maps in calib. DB"<<endl;
140
141 if(false){ // save this to work off configuration parameter
142 jout<<"Will read in the following:"<<endl;
143 for(unsigned int i=0; i<material_namepaths.size(); i++){
144 jout<<" "<<material_namepaths[i]<<endl;
145 }
146 }
147
148 // Actually read in the maps
149 uint32_t Npoints_total=0;
150 //cout<<endl; // make empty line so material map can overwrite it below
151 for(unsigned int i=0; i<material_namepaths.size(); i++){
152 // DMaterialMap constructor prints line so we conserve real
153 // estate by having each recycle the line
154 //cout<<ansi_up(1)<<string(85, ' ')<<"\r";
155 DMaterialMap *mat = new DMaterialMap(material_namepaths[i], jcalib);
156 if( ! mat->IS_VALID ) {
157 // This particular map may not exist for this run/variation
158 // (e.g. CPP uses maps downstream of TOF)
159 delete mat;
160 continue;
161 }
162 materialmaps.push_back(mat);
163 Npoints_total += (unsigned int)(mat->GetNr()*mat->GetNz());
164 }
165 //cout<<ansi_up(1)<<string(85, ' ')<<"\r";
166 jout<<"Read in "<<materialmaps.size()<<" material maps for run "<<runnumber<<" containing "<<Npoints_total<<" grid points total"<<endl;
167
168 // Set flag that maps have been read and unlock mutex
169 materialmaps_read = true;
170 pthread_mutex_unlock(&materialmap_mutex);
171}
172
173//---------------------------------
174// FindNodes
175//---------------------------------
176void DGeometry::FindNodes(string xpath, vector<xpathparsed_t> &matched_xpaths) const
177{
178 /// Find all nodes that match the specified xpath and return them as
179 /// fully parsed lists of the nodes and attributes.
180 ///
181 /// The matched_xpaths variable has 4 levels of STL containers nested
182 /// together! The node_t data type contains 2 of them and represents
183 /// a single tag with the "first" member being the tag name
184 /// and the "second" member being a map of all of the attributes
185 /// of that tag along with their values.
186 ///
187 /// The xpathparsed_t data type is a STL vector of node_t objects
188 /// that comprises a complete xpath. The data type of matched_xpaths
189 /// is a STL vector if xpathparsed_t objects and so comprises a
190 /// list of complete xpaths.
191
192 /// We do this by calling the GetXPaths() method of JGeometry to get
193 /// a list of all xpaths. Then we pass all of those in to
194 /// JGeometryXML::ParseXPath() to get a parsed list for each. This
195 /// is compared to the parsed values of the xpath passed to us
196 /// (also parsed by JGeometryXML::ParseXPath()) to find matches.
197
198 // Make sure matched_xpaths is empty
199 matched_xpaths.clear();
200
201 // Cast JGeometry into a JGeometryXML
202 JGeometryXML *jgeomxml = dynamic_cast<JGeometryXML*>(jgeom);
203
204 // Parse our target xpath
205 xpathparsed_t target;
206 string unused_string;
207 unsigned int unused_int;
208 jgeomxml->ParseXPath(xpath, target, unused_string, unused_int);
209
210 // Get all xpaths for current geometry source
211 vector<string> allxpaths;
212 jgeom->GetXPaths(allxpaths, JGeometry::attr_level_all);
213
214 // Loop over xpaths
215 for(unsigned int i=0; i<allxpaths.size(); i++);
216}
217
218//---------------------------------
219// FindMatALT1 - parameters for alt1 fitter.
220//---------------------------------
221jerror_t DGeometry::FindMatALT1(DVector3 &pos, DVector3 &mom,double &KrhoZ_overA,
222 double &rhoZ_overA,double &LnI,
223 double &X0, double *s_to_boundary) const
224{
225// ReadMaterialMaps();
226
227 for(unsigned int i=0; i<materialmaps.size(); i++){
228 jerror_t err = materialmaps[i]->FindMatALT1(pos,KrhoZ_overA, rhoZ_overA,LnI,X0);
229 if(err==NOERROR){
230 // We found the material map containing this point. If a non-NULL
231 // pointer was passed in for s_to_boundary, then search through all
232 // material maps above and including this one to find the estimated
233 // distance to the nearest boundary the swimmer should step to. Maps
234 // after this one would only be considered outside of this one so
235 // there is no need to check them.
236 if(s_to_boundary==NULL__null)return NOERROR; // User doesn't want distance to boundary
237 *s_to_boundary = 1.0E6;
238 for(unsigned int j=0; j<=i; j++){
239 double s = materialmaps[j]->EstimatedDistanceToBoundary(pos, mom);
240 if(s<*s_to_boundary)*s_to_boundary = s;
241 }
242 return NOERROR;
243 }
244 }
245 return RESOURCE_UNAVAILABLE;
246}
247
248
249
250
251//---------------------------------
252// FindMatKalman - Kalman filter needs slightly different set of parms.
253//---------------------------------
254jerror_t DGeometry::FindMatKalman(const DVector3 &pos,const DVector3 &mom,
255 double &KrhoZ_overA,
256 double &rhoZ_overA,
257 double &LnI,double &Z,
258 double &chi2c_factor,double &chi2a_factor,
259 double &chi2a_corr,
260 unsigned int &last_index,
261 double *s_to_boundary) const
262{
263// ReadMaterialMaps();
264
265 //last_index=0;
266 for(unsigned int i=last_index; i<materialmaps.size(); i++){
267 jerror_t err = materialmaps[i]->FindMatKalman(pos,KrhoZ_overA,
268 rhoZ_overA,LnI,chi2c_factor,
269 chi2a_factor,chi2a_corr,Z);
270 if(err==NOERROR){
271 if(i==materialmaps.size()-1) last_index=0;
272 else last_index=i;
273 if(s_to_boundary==NULL__null)return NOERROR; // User doesn't want distance to boundary
274
275 *s_to_boundary = 1.0E6;
276 // If we are in the main mother volume, search through all the maps for
277 // the nearest boundary
278 if(last_index==0){
279 for(unsigned int j=0; j<materialmaps.size();j++){
280 double s = materialmaps[j]->EstimatedDistanceToBoundary(pos, mom);
281 if(s<*s_to_boundary){
282 *s_to_boundary = s;
283 }
284 }
285 }
286 else{
287 // otherwise, we found the material map containing this point.
288 double s = materialmaps[last_index]->EstimatedDistanceToBoundary(pos, mom);
289 if(s<*s_to_boundary)*s_to_boundary = s;
290 }
291 return NOERROR;
292 }
293 }
294
295return RESOURCE_UNAVAILABLE;
296}
297
298jerror_t DGeometry::FindMatKalman(const DVector3 &pos,const DVector3 &mom,
299 double &KrhoZ_overA,
300 double &rhoZ_overA,
301 double &LnI,double &Z,
302 unsigned int &last_index,
303 double *s_to_boundary) const
304{
305// ReadMaterialMaps();
306
307 //last_index=0;
308 for(unsigned int i=last_index; i<materialmaps.size(); i++){
309 jerror_t err = materialmaps[i]->FindMatKalman(pos,KrhoZ_overA,
310 rhoZ_overA,LnI,Z);
311 if(err==NOERROR){
312 if(i==materialmaps.size()-1) last_index=0;
313 else last_index=i;
314 if(s_to_boundary==NULL__null)return NOERROR; // User doesn't want distance to boundary
315
316 *s_to_boundary = 1.0E6;
317 // If we are in the main mother volume, search through all the maps for
318 // the nearest boundary
319 if(last_index==0){
320 for(unsigned int j=0; j<materialmaps.size();j++){
321 double s = materialmaps[j]->EstimatedDistanceToBoundary(pos, mom);
322 if(s<*s_to_boundary){
323 *s_to_boundary = s;
324 }
325 }
326 }
327 else{
328 // otherwise, we found the material map containing this point.
329 double s = materialmaps[last_index]->EstimatedDistanceToBoundary(pos, mom);
330 if(s<*s_to_boundary)*s_to_boundary = s;
331 }
332 return NOERROR;
333 }
334 }
335
336return RESOURCE_UNAVAILABLE;
337}
338
339//---------------------------------
340jerror_t DGeometry::FindMatKalman(const DVector3 &pos,
341 double &KrhoZ_overA,
342 double &rhoZ_overA,
343 double &LnI, double &Z,double &chi2c_factor,
344 double &chi2a_factor, double &chi2a_corr,
345 unsigned int &last_index) const
346{
347// ReadMaterialMaps();
348
349 //last_index=0;
350 for(unsigned int i=last_index; i<materialmaps.size(); i++){
351 jerror_t err = materialmaps[i]->FindMatKalman(pos,KrhoZ_overA,
352 rhoZ_overA,LnI,
353 chi2c_factor,chi2a_factor,
354 chi2a_corr,Z);
355 if(err==NOERROR){
356 if(i==materialmaps.size()-1) last_index=0;
357 else last_index=i;
358 return err;
359 }
360 }
361
362 return RESOURCE_UNAVAILABLE;
363}
364
365//---------------------------------
366// Get material properties needed for dEdx
367jerror_t DGeometry::FindMatKalman(const DVector3 &pos,
368 double &KrhoZ_overA,
369 double &rhoZ_overA,
370 double &LnI, double &Z,
371 unsigned int &last_index) const
372{
373// ReadMaterialMaps();
374
375 //last_index=0;
376 for(unsigned int i=last_index; i<materialmaps.size(); i++){
377 jerror_t err = materialmaps[i]->FindMatKalman(pos,KrhoZ_overA,
378 rhoZ_overA,LnI,Z);
379 if(err==NOERROR){
380 if(i==materialmaps.size()-1) last_index=0;
381 else last_index=i;
382 return err;
383 }
384 }
385
386 return RESOURCE_UNAVAILABLE;
387}
388
389
390
391
392//---------------------------------
393// FindMat
394//---------------------------------
395jerror_t DGeometry::FindMat(DVector3 &pos, double &rhoZ_overA, double &rhoZ_overA_logI, double &RadLen) const
396{
397// ReadMaterialMaps();
398
399 for(unsigned int i=0; i<materialmaps.size(); i++){
400 jerror_t err = materialmaps[i]->FindMat(pos, rhoZ_overA, rhoZ_overA_logI, RadLen);
401 if(err==NOERROR)return NOERROR;
402 }
403 return RESOURCE_UNAVAILABLE;
404}
405
406//---------------------------------
407// FindMat
408//---------------------------------
409jerror_t DGeometry::FindMat(DVector3 &pos, double &density, double &A, double &Z, double &RadLen) const
410{
411// ReadMaterialMaps();
412
413 for(unsigned int i=0; i<materialmaps.size(); i++){
414 jerror_t err = materialmaps[i]->FindMat(pos, density, A, Z, RadLen);
415 if(err==NOERROR)return NOERROR;
416 }
417 return RESOURCE_UNAVAILABLE;
418}
419
420//---------------------------------
421// FindMatNode
422//---------------------------------
423//const DMaterialMap::MaterialNode* DGeometry::FindMatNode(DVector3 &pos) const
424//{
425//
426//}
427
428//---------------------------------
429// FindDMaterialMap
430//---------------------------------
431const DMaterialMap* DGeometry::FindDMaterialMap(DVector3 &pos) const
432{
433// ReadMaterialMaps();
434
435 for(unsigned int i=0; i<materialmaps.size(); i++){
436 const DMaterialMap* map = materialmaps[i];
437 if(map->IsInMap(pos))return map;
438 }
439 return NULL__null;
440}
441
442//====================================================================
443// Convenience Methods
444//
445// Below are defined some methods to make it easy to extract certain
446// key values about the GlueX detector geometry from the XML source.
447// Note that one can still use the generic Get(string xpath, ...)
448// methods. This just packages some of them up for convenience.
449//
450// The one real gotcha here is that these methods must be kept
451// in sync with the XML structure by hand. If volumes are renamed
452// or their location within the hierachy is modified, then these
453// routines will need to be modified as well. That, or course, is
454// also true if you are using the generic Get(...) methods.
455//
456// What these methods are useful for is when minor changes are made
457// to the XML (such as the locations of the FDC packages) they
458// are automatically reflected here.
459//====================================================================
460
461//---------------------------------
462// GetDMaterial
463//---------------------------------
464const DMaterial* DGeometry::GetDMaterial(string name) const
465{
466 /// Get a pointer to the DMaterial object with the specified name.
467 // Only fill materials member when one is actually requested
468 // and then, only fill it once.
469
470 // Lock mutex so we can check flag to see if maps have already
471 // been read in
472 pthread_mutex_lock(&materials_mutex);
473 if(!materials_read) GetMaterials();
474 pthread_mutex_unlock(&materials_mutex);
475
476 for(unsigned int i=0; i<materials.size(); i++){
477 if(materials[i]->GetName() == name)return materials[i];
478 }
479
480 //_DBG_<<"No material \""<<name<<"\" found ("<<materials.size()<<" materials defined)"<<endl;
481
482 return NULL__null;
483}
484
485//---------------------------------
486// GetMaterials
487//---------------------------------
488void DGeometry::GetMaterials(void) const
489{
490 /// Read in all of the materials from the geometry source and create
491 /// a DMaterial object for each one.
492
493 //=========== elements ===========
494 string filter = "//materials/element/real[@name=\"radlen\"]";
495
496 // Get list of all xpaths
497 vector<string> xpaths;
498 jgeom->GetXPaths(xpaths, JGeometry::attr_level_all, filter);
499
500 // Look for xpaths that have "/materials[" in them
501 for(unsigned int i=0; i<xpaths.size(); i++){
502 // Get start of "element" section
503 string::size_type pos = xpaths[i].find("/element[");
504 if(pos == string::npos)continue;
505
506 // Get name attribute
507 string::size_type start_pos = xpaths[i].find("@name=", pos);
508 start_pos = xpaths[i].find("'", start_pos);
509 string::size_type end_pos = xpaths[i].find("'", start_pos+1);
510 if(end_pos==string::npos)continue;
511 string name = xpaths[i].substr(start_pos+1, end_pos-(start_pos+1));
512
513 // Get values
514 char xpath[256];
515
516 double A;
517 sprintf(xpath,"//materials/element[@name='%s']/[@a]", name.c_str());
518 if(!Get(xpath, A))continue;
519
520 double Z;
521 sprintf(xpath,"//materials/element[@name='%s']/[@z]", name.c_str());
522 if(!Get(xpath, Z))continue;
523
524 double density;
525 sprintf(xpath,"//materials/element[@name='%s']/real[@name='density']/[@value]", name.c_str());
526 if(!Get(xpath, density))continue;
527
528 double radlen;
529 sprintf(xpath,"//materials/element[@name='%s']/real[@name='radlen']/[@value]", name.c_str());
530 if(!Get(xpath, radlen))continue;
531
532 DMaterial *mat = new DMaterial(name, A, Z, density, radlen);
533 materials.push_back(mat);
534
535 cout<<mat->toString();
536 }
537
538 //=========== composites ===========
539 filter = "//materials/composite[@name]";
540
541 // Get list of all xpaths
542 jgeom->GetXPaths(xpaths, JGeometry::attr_level_all, filter);
543
544 // Look for xpaths that have "/materials[" in them
545 for(unsigned int i=0; i<xpaths.size(); i++){
546 // Get start of "composite" section
547 string::size_type pos = xpaths[i].find("/composite[");
548 if(pos == string::npos)continue;
549
550 // Get name attribute
551 string::size_type start_pos = xpaths[i].find("@name=", pos);
552 start_pos = xpaths[i].find("'", start_pos);
553 string::size_type end_pos = xpaths[i].find("'", start_pos+1);
554 if(end_pos==string::npos)continue;
555 string name = xpaths[i].substr(start_pos+1, end_pos-(start_pos+1));
556
557 if(GetDMaterial(name))continue; // skip duplicates
558
559 // Get values
560 char xpath[256];
561
562 // We should calculate an effective A and Z .... but we don't
563 bool found_all=true;
564 double A=0;
565 double Z=0;
566
567 double density;
568 sprintf(xpath,"//materials/composite[@name='%s']/real[@name='density']/[@value]", name.c_str());
569 found_all &= Get(xpath, density);
570
571 double radlen;
572 sprintf(xpath,"//materials/composite[@name='%s']/real[@name='radlen']/[@value]", name.c_str());
573 found_all &= Get(xpath, radlen);
574
575 // If we didn't find the info we need (radlen and density) in the
576 // composite tag itself. Try calculating them from the components
577 if(!found_all)found_all = GetCompositeMaterial(name, density, radlen);
578
579 // If we weren't able to get the values needed to make the DMaterial object
580 // then skip this one.
581 if(!found_all)continue;
582
583 DMaterial *mat = new DMaterial(name, A, Z, density, radlen);
584 materials.push_back(mat);
585
586 cout<<mat->toString();
587 }
588
589 materials_read = true;
590}
591
592//---------------------------------
593// GetCompositeMaterial
594//---------------------------------
595bool DGeometry::GetCompositeMaterial(const string &name, double &density, double &radlen) const
596{
597 // Get list of all xpaths with "addmaterial" and "fractionmass"
598 char filter[512];
599 sprintf(filter,"//materials/composite[@name='%s']/addmaterial/fractionmass[@fraction]", name.c_str());
600 vector<string> xpaths;
601 jgeom->GetXPaths(xpaths, JGeometry::attr_level_all, filter);
602
603 // Loop over components of this composite
604_DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<604<<" "
<<"Components for compsite "<<name<<endl;
605 for(unsigned int i=0; i<xpaths.size(); i++){
606 // Get component material name
607 string::size_type start_pos = xpaths[i].find("@material=", 0);
608 start_pos = xpaths[i].find("'", start_pos);
609 string::size_type end_pos = xpaths[i].find("'", start_pos+1);
610 if(end_pos==string::npos)continue;
611 string mat_name = xpaths[i].substr(start_pos+1, end_pos-(start_pos+1));
612
613 // Get component mass fraction
614 start_pos = xpaths[i].find("fractionmass[", 0);
615 start_pos = xpaths[i].find("@fraction=", start_pos);
616 start_pos = xpaths[i].find("'", start_pos);
617 end_pos = xpaths[i].find("'", start_pos+1);
618 if(end_pos==string::npos)continue;
619 string mat_frac_str = xpaths[i].substr(start_pos+1, end_pos-(start_pos+1));
620 double fractionmass = atof(mat_frac_str.c_str());
621
622 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<622<<" "
<<" "<<xpaths[i]<<" fractionmass="<<fractionmass<<endl;
623 }
624
625 return true;
626}
627
628//---------------------------------
629// GetTraversedMaterialsZ
630//---------------------------------
631//void DGeometry::GetTraversedMaterialsZ(double q, const DVector3 &pos, const DVector3 &mom, double z_end, vector<DMaterialStep> &materialsteps)
632//{
633 /// Find the materials traversed by a particle swimming from a specific
634 /// position with a specific momentum through the magnetic field until
635 /// it reaches a specific z-location. Energy loss is not included in
636 /// the swimming since this method itself is assumed to be one of the
637 /// primary means of determining energy loss. As such, one should not
638 /// pass in a value of z_end that is far from pos.
639 ///
640 /// The vector materialsteps will be filled with DMaterialStep objects
641 /// corresponding to each of the materials traversed.
642 ///
643 /// The real work here is done by the DMaterialStepper class
644
645//}
646
647//---------------------------------
648// GetCDCStereoWires
649//---------------------------------
650/// Extract the stereo wire data from the XML
651bool DGeometry::GetCDCStereoWires(unsigned int ring,unsigned int ncopy,
652 double zcenter,double dz,
653 vector<vector<cdc_offset_t> >&cdc_offsets,
654 vector<DCDCWire*> &stereowires,
655 vector<double>&rot_angles,double dx,
656 double dy) const{
657 stringstream r_z_s,phi0_s,rot_s;
658
659 // Create search strings for the straw geometrical properties
660 r_z_s << "//mposPhi[@volume='CDCstrawLong']/@R_Z/ring[@value='" << ring << "']";
661 phi0_s << "//mposPhi[@volume='CDCstrawLong']/@Phi0/ring[@value='" << ring << "']";
662 rot_s << "//mposPhi[@volume='CDCstrawLong']/@rot/ring[@value='" << ring << "']";
663
664 vector<double>r_z;
665 double phi0;
666 vector<double>rot;
667
668 // Extract data from the XML
669 if(!Get(r_z_s.str(), r_z)) return false;
670 if(!Get(phi0_s.str(), phi0)) return false;
671 if(!Get(rot_s.str(), rot)) return false;
672
673 // Angular quantities
674 const double deg2rad=M_PI3.14159265358979323846/180.;
675 double dphi=2*M_PI3.14159265358979323846/double(ncopy);
676 phi0*=deg2rad;
677
678 // Extract data from close-packed straws
679 double stereo=0.,stereo_sign=1.;
680 stereo=deg2rad*rot[0];
681 if (stereo<0.) stereo_sign=-1.;
682
683 // Loop over the number of straws
684 for (unsigned int i=0;i<ncopy;i++){
685 DCDCWire *w=new DCDCWire;
686 double phi=phi0+double(i)*dphi;
687 w->ring=ring;
688 w->straw=i+1;
689
690 // Find the nominal wire position and direction from the XML
691 DVector3 origin,udir;
692 origin.SetX(r_z[0]*cos(phi)+dx);
693 origin.SetY(r_z[0]*sin(phi)+dy);
694 origin.SetZ(zcenter);
695
696 // Here, we need to define a coordinate system for the wire
697 // in which the wire runs along one axis. We call the directions
698 // of the axes in this coordinate system s,t, and u with
699 // the wire running in the "u" direction. The "s" direction
700 // will be defined by the direction pointing from the beamline
701 // to the midpoint of the wire.
702 udir.SetXYZ(0.0, 0.0,1.0);
703 udir.RotateX(stereo);
704 udir.RotateZ(phi);
705
706 // Apply offsets in x and y
707 double half_dz=0.5*dz;
708 double x0=origin.x(),y0=origin.y();
709 double ux=udir.x()/udir.z();
710 double uy=udir.y()/udir.z();
711 unsigned int ringid=ring-1;
712 DVector3 downstream(x0+half_dz*ux+cdc_offsets[ringid][i].dx_d,
713 y0+half_dz*uy+cdc_offsets[ringid][i].dy_d,
714 zcenter+half_dz);
715 DVector3 upstream(x0-half_dz*ux+cdc_offsets[ringid][i].dx_u,
716 y0-half_dz*uy+cdc_offsets[ringid][i].dy_u,
717 zcenter-half_dz);
718 w->origin=0.5*(upstream+downstream);
719 w->origin.RotateX(rot_angles[0]);
720 w->origin.RotateY(rot_angles[1]);
721 w->origin.RotateZ(rot_angles[2]);
722
723 w->phi=w->origin.Phi();
724
725 // Wire direction
726 w->udir=downstream-upstream;
727 w->udir.RotateX(rot_angles[0]);
728 w->udir.RotateY(rot_angles[1]);
729 w->udir.RotateZ(rot_angles[2]);
730
731 // For derivatives
732 w->udir_mag=w->udir.Mag();
733
734 w->udir.SetMag(1.);
735 w->stereo=stereo_sign*w->udir.Angle(DVector3(0.,0.,1.));
736 // other directions for our wire coordinate system
737 w->sdir=w->origin;
738 w->sdir.SetMag(1.);
739 w->tdir = w->udir.Cross(w->sdir);
740
741 // Some values needed for alignment derivatives
742 w->x0=dx; w->y0=dy; w->z0=zcenter;
743 w->phiX=rot_angles[0]; w->phiY=rot_angles[1]; w->phiZ=rot_angles[2];
744 w->r0=r_z[0]; w->phiStraw=phi; w->stereo_raw=stereo;
745
746 stereowires.push_back(w);
747 }
748
749 return true;
750}
751
752//---------------------------------
753// GetCDCAxialWires
754//---------------------------------
755/// Extract the axial wire data from the XML
756bool DGeometry::GetCDCAxialWires(unsigned int ring,unsigned int ncopy,
757 double zcenter,double dz,
758 vector<vector<cdc_offset_t> >&cdc_offsets,
759 vector<DCDCWire*> &axialwires,
760 vector<double>&rot_angles,double dx,
761 double dy) const{
762 stringstream phi0_s,r_z_s;
763
764 // Create search strings for the number of straws and the straw geometrical properties
765 phi0_s << "//mposPhi[@volume='CDCstrawShort']/@Phi0/ring[@value='" << ring << "']";
766 r_z_s << "//mposPhi[@volume='CDCstrawShort']/@R_Z/ring[@value='" << ring << "']";
767
768 double phi0;
769 vector<double>r_z;
770
771 // Extract the data from the XML
772 if(!Get(phi0_s.str(), phi0)) return false;
773 if(!Get(r_z_s.str(), r_z)) return false;
774
775 // Angular quantities
776 double dphi=2*M_PI3.14159265358979323846/double(ncopy);
777 phi0*=M_PI3.14159265358979323846/180.;
778
779 // Loop over the number of straws
780 for (unsigned int i=0;i<ncopy;i++){
781 DCDCWire *w=new DCDCWire;
782 double phi=phi0+double(i)*dphi;
783 w->ring=ring;
784 w->straw=i+1;
785
786 // Find the nominal wire position from the XML
787 double x0=r_z[0]*cos(phi)+dx;
788 double y0=r_z[0]*sin(phi)+dy;
789
790 // Apply offsets in x and y
791 double half_dz=0.5*dz;
792 unsigned int ringid=ring-1;
793 DVector3 downstream(x0+cdc_offsets[ringid][i].dx_d,
794 y0+cdc_offsets[ringid][i].dy_d,
795 zcenter+half_dz);
796 DVector3 upstream(x0+cdc_offsets[ringid][i].dx_u,
797 y0+cdc_offsets[ringid][i].dy_u,
798 zcenter-half_dz);
799 w->origin=0.5*(upstream+downstream);
800 w->origin.RotateX(rot_angles[0]);
801 w->origin.RotateY(rot_angles[1]);
802 w->origin.RotateZ(rot_angles[2]);
803 w->phi=w->origin.Phi();
804
805 // Here, we need to define a coordinate system for the wire
806 // in which the wire runs along one axis. We call the directions
807 // of the axes in this coordinate system s,t, and u with
808 // the wire running in the "u" direction. The "s" direction
809 // will be defined by the direction pointing from the beamline
810 // to the midpoint of the wire.
811 w->udir=downstream-upstream;
812 w->udir.RotateX(rot_angles[0]);
813 w->udir.RotateY(rot_angles[1]);
814 w->udir.RotateZ(rot_angles[2]);
815
816 // For derivatives
817 w->udir_mag=w->udir.Mag();
818
819 w->udir.SetMag(1.);
820
821 w->stereo=w->udir.Angle(DVector3(0.,0.,1.));
822 // other directions for our wire coordinate system
823 w->sdir=w->origin;
824 w->sdir.SetMag(1.);
825 w->tdir = w->udir.Cross(w->sdir);
826
827 // Some values needed for alignment derivatives
828 w->x0=dx; w->y0=dy; w->z0=zcenter;
829 w->phiX=rot_angles[0]; w->phiY=rot_angles[1]; w->phiZ=rot_angles[2];
830 w->r0=r_z[0]; w->phiStraw=phi; w->stereo_raw=0.0;
831
832 axialwires.push_back(w);
833 }
834
835 return true;
836}
837
838//---------------------------------
839// GetCDCWires
840//---------------------------------
841bool DGeometry::GetCDCWires(vector<vector<DCDCWire *> >&cdcwires) const{
842 // Get nominal geometry from XML
843 vector<double>cdc_origin;
844 vector<double>cdc_length;
845 Get("//posXYZ[@volume='CentralDC']/@X_Y_Z",cdc_origin);
846 Get("//tubs[@name='STRW']/@Rio_Z",cdc_length);
847
848 // Get CDC rotation angles
849 vector<double>rot_angles;
850 Get("//posXYZ[@volume='CentralDC']/@rot", rot_angles);
851 rot_angles[0]*=M_PI3.14159265358979323846/180.;
852 rot_angles[1]*=M_PI3.14159265358979323846/180.;
853 rot_angles[2]*=M_PI3.14159265358979323846/180.;
854
855 double dX=0.0, dY=0.0, dZ=0.0;
856 double dPhiX=0.0,dPhiY=0.0,dPhiZ=0.0;
857
858 JCalibration * jcalib = dapp->GetJCalibration(runnumber);
859 vector<map<string,double> >vals;
860 if (jcalib->Get("CDC/global_alignment",vals)==false){
861 map<string,double> &row = vals[0];
862 dX=row["dX"];
863 dY=row["dY"];
864 dZ=row["dZ"];
865 dPhiX=row["dPhiX"];
866 dPhiY=row["dPhiY"];
867 dPhiZ=row["dPhiZ"];
868 }
869
870
871 // Shift the CDC origin according to alignment
872 cdc_origin[0]+=dX;
873 cdc_origin[1]+=dY;
874 cdc_origin[2]+=dZ;
875
876 // Shift the CDC rotation according to the alignment
877 rot_angles[0]+=dPhiX;
878 rot_angles[1]+=dPhiY;
879 rot_angles[2]+=dPhiZ;
880
881 double zmin=cdc_origin[2];
882 double zmax=zmin+cdc_length[2];
883 double zcenter=0.5*(zmin+zmax);
884 double L=zmax-zmin;
885
886 // Get number of straws for each layer from the XML
887 unsigned int numstraws[28];
888 stringstream ncopy_s;
889
890 // Get number of straws for each ring
891 for (unsigned int ring=1;ring<=28;ring++){
892 // Create search string for the number of straws
893 ncopy_s << "//section[@name='CentralDC']/composition/mposPhi/@ncopy/ring[@value='" << ring << "']";
894 Get(ncopy_s.str(),numstraws[ring-1]);
895 ncopy_s.str("");
896 ncopy_s.clear();
897 }
898
899 // Get straw-by-straw offsets from calibration database
900 vector<cdc_offset_t>tempvec;
901 vector<vector<cdc_offset_t> >cdc_offsets;
902
903 if (jcalib->Get("CDC/wire_alignment",vals)==false){
904 unsigned int straw_count=0,ring_count=0;
905 for(unsigned int i=0; i<vals.size(); i++){
906 map<string,double> &row = vals[i];
907
908 // put the vector of offsets for the current ring into the offsets vector
909 if (straw_count==numstraws[ring_count]){
910 straw_count=0;
911 ring_count++;
912
913 cdc_offsets.push_back(tempvec);
914
915 tempvec.clear();
916 }
917
918 // Get the offsets from the calibration database
919 cdc_offset_t temp;
920 temp.dx_u=row["dxu"];
921 //temp.dx_u=0.;
922
923 temp.dy_u=row["dyu"];
924 //temp.dy_u=0.;
925
926 temp.dx_d=row["dxd"];
927 //temp.dx_d=0.;
928
929 temp.dy_d=row["dyd"];
930 //temp.dy_d=0.;
931
932 tempvec.push_back(temp);
933
934 straw_count++;
935 }
936 cdc_offsets.push_back(tempvec);
937 }
938 else{
939 jerr<< "CDC wire alignment table not available... bailing... " <<endl;
940 exit(0);
941 }
942
943 // First axial layer
944 for (unsigned int ring=1;ring<5;ring++){
945 vector<DCDCWire*>straws;
946 if (!GetCDCAxialWires(ring,numstraws[ring-1],zcenter,L,cdc_offsets,straws,
947 rot_angles,cdc_origin[0],cdc_origin[1])) return false;
948 cdcwires.push_back(straws);
949 }
950
951 // First set of stereo layers
952 for (unsigned int i=0;i<8;i++){
953 vector<DCDCWire*>straws;
954 if (!GetCDCStereoWires(i+5,numstraws[i+4],zcenter,L,cdc_offsets,straws,
955 rot_angles,cdc_origin[0],cdc_origin[1])) return false;
956 cdcwires.push_back(straws);
957 }
958
959 // Second axial layer
960 for (unsigned int ring=13;ring<17;ring++){
961 vector<DCDCWire*>straws;
962 if (!GetCDCAxialWires(ring,numstraws[ring-1],zcenter,L,cdc_offsets,straws,
963 rot_angles,cdc_origin[0],cdc_origin[1])) return false;
964 cdcwires.push_back(straws);
965 }
966
967 // Second set of stereo layers
968 for (unsigned int i=8;i<16;i++){
969 vector<DCDCWire*>straws;
970 if (!GetCDCStereoWires(i+9,numstraws[i+8],zcenter,L,cdc_offsets,straws,
971 rot_angles,cdc_origin[0],cdc_origin[1])) return false;
972 cdcwires.push_back(straws);
973 }
974
975 // Third axial layer
976 for (unsigned int ring=25;ring<29;ring++){
977 vector<DCDCWire*>straws;
978 if (!GetCDCAxialWires(ring,numstraws[ring-1],zcenter,L,cdc_offsets,straws,
979 rot_angles,cdc_origin[0],cdc_origin[1])) return false;
980 cdcwires.push_back(straws);
981 }
982
983 // Calculate wire lengths and compute "s" and "t" direction vectors (orthogonal to "u")
984 for (unsigned int i=0;i<cdcwires.size();i++){
985 for (unsigned int j=0;j<cdcwires[i].size();j++){
986 DCDCWire *w=cdcwires[i][j];
987 w->L=L/cos(w->stereo);
988
989 // With the addition of close-packed stereo wires, the vector connecting
990 // the center of the wire to the beamline ("s" direction) is not necessarily
991 // perpendicular to the beamline. By definition, we want the "s" direction
992 // to be perpendicular to the wire direction "u" and pointing at the beamline.
993 //
994 // NOTE: This extensive comment is here because the result, when implmented
995 // below caused a WORSE residual distribution in the close-packed stereo
996 // layers. Owing to lack of time currently to track the issue down (most
997 // likely in DReferenceTrajectory) I'm commenting out the "correct" calculation
998 // of s, but leaving this comment so the issue can be revisited later. This
999 // error leads to around 100 micron errors in the C.P.S. wires, but they
1000 // are completely washed out when the position smearing of 150 microns is applied
1001 // making the error unnoticable except when position smearing is not applied.
1002 //
1003 // April 2, 2009 D.L.
1004 //
1005 // Here is how this is calculated -- We define a vector equation with 2 unknowns
1006 // Z and S:
1007 //
1008 // Zz + Ss = W
1009 //
1010 // where: z = unit vector in z direction
1011 // s = unit vector in "s" direction
1012 // W = vector pointing to center of wire in lab coordinates
1013 //
1014 // Rearranging, we get:
1015 //
1016 // s = (W - Zz)/S
1017 //
1018 // Since s must be perpendicular to u, we take a dot product of s and u
1019 // and set it equal to zero to determine Z:
1020 //
1021 // u.s = 0 = u.(W - Zz)/S => u.W = Zu.z
1022 //
1023 // or
1024 //
1025 // Z = u.W/u.z
1026 //
1027 // Thus, the s direction is just given by (W - (u.W/u.z)z)
1028 //
1029
1030 //w->sdir=w->origin-DVector3(0,0,w->origin.Z());
1031 w->sdir = w->origin - DVector3(0.0, 0.0, w->udir.Dot(w->origin)/w->udir.Z()); // see above comments
1032 w->sdir.SetMag(1.0);
1033
1034 w->tdir = w->udir.Cross(w->sdir);
1035 w->tdir.SetMag(1.0); // This isn't really needed
1036 }
1037 }
1038
1039 return true;
1040}
1041
1042
1043//---------------------------------
1044// GetFDCCathodes
1045//---------------------------------
1046bool DGeometry::GetFDCCathodes(vector<vector<DFDCCathode *> >&fdccathodes) const{
1047 // Get offsets tweaking nominal geometry from calibration database
1048 JCalibration * jcalib = dapp->GetJCalibration(runnumber);
1049 vector<map<string,double> >vals;
1050 vector<fdc_cathode_offset_t>fdc_cathode_offsets;
1051 if (jcalib->Get("FDC/cathode_alignment",vals)==false){
1052 for(unsigned int i=0; i<vals.size(); i++){
1053 map<string,double> &row = vals[i];
1054
1055 // Get the offsets from the calibration database
1056 fdc_cathode_offset_t temp;
1057 temp.du=row["dU"];
1058 //temp.du=0.;
1059
1060 temp.dphi=row["dPhiU"];
1061 //temp.dphi=0.;
1062
1063 fdc_cathode_offsets.push_back(temp);
1064
1065 temp.du=row["dV"];
1066 //temp.du=0.;
1067
1068 temp.dphi=row["dPhiV"];
1069 //temp.dphi=0.;
1070
1071 fdc_cathode_offsets.push_back(temp);
1072 }
1073 }
1074 vector< vector<double> >fdc_cathode_pitches;
1075 if (jcalib->Get("FDC/strip_pitches_v2",vals)==false){
1076 for(unsigned int i=0; i<vals.size(); i++){
1077 map<string,double> &row = vals[i];
1078
1079 vector<double> uvals;
1080 // Get the offsets from the calibration database
1081 uvals.push_back(row["U_SP_1"]);
1082 uvals.push_back(row["U_G_1"]);
1083 uvals.push_back(row["U_SP_2"]);
1084 uvals.push_back(row["U_G_2"]);
1085 uvals.push_back(row["U_SP_3"]);
1086
1087 fdc_cathode_pitches.push_back(uvals);
1088
1089 vector<double> vvals;
1090 // Get the offsets from the calibration database
1091 vvals.push_back(row["V_SP_1"]);
1092 vvals.push_back(row["V_G_1"]);
1093 vvals.push_back(row["V_SP_2"]);
1094 vvals.push_back(row["V_G_2"]);
1095 vvals.push_back(row["V_SP_3"]);
1096
1097 fdc_cathode_pitches.push_back(vvals);
1098 }
1099 }
1100 else{
1101 jerr << "Strip pitch calibration unavailable -- setting default..." <<endl;
1102 // set some sensible default
1103 for (unsigned int i=0;i<2*FDC_NUM_LAYERS24;i++){
1104
1105 vector<double> val;
1106 for (int j = 0; j < 5; j++){
1107 val.push_back(STRIP_SPACING0.500);
1108 }
1109
1110 fdc_cathode_pitches.push_back(val);
1111 }
1112 }
1113
1114 // Generate the vector of cathode plane parameters
1115 for (int i=0;i<2*FDC_NUM_LAYERS24; i++){
1116 double angle=(i%2)?(M_PI3.14159265358979323846-CATHODE_ROT_ANGLE1.309):(CATHODE_ROT_ANGLE1.309);
1117
1118 angle+=fdc_cathode_offsets[i].dphi;
1119 double SP1 = fdc_cathode_pitches[i][0];
1120 double SG1 = fdc_cathode_pitches[i][1];
1121 double SP2 = fdc_cathode_pitches[i][2];
1122 double SG2 = fdc_cathode_pitches[i][3];
1123 double SP3 = fdc_cathode_pitches[i][4];
1124
1125 vector<DFDCCathode *>temp;
1126 for (int j=0; j<STRIPS_PER_PLANE192; j++){
1127 DFDCCathode *c = new DFDCCathode;
1128 c->layer = i+1;
1129 c->strip = j+1;
1130 c->angle = angle;
1131 if (j<48) c->u=(-47.5*SP2 - SG1 + (j-47)*SP1) + fdc_cathode_offsets[i].du;
1132 else if (j<144) c->u=(double(j)-95.5)*SP2 + fdc_cathode_offsets[i].du;
1133 else c->u=(47.5*SP2 + SG2 + (j-144)*SP3) + fdc_cathode_offsets[i].du;
1134
1135 temp.push_back(c);
1136 }
1137 fdccathodes.push_back(temp);
1138 }
1139
1140 return true;
1141}
1142
1143//---------------------------------
1144// GetFDCWires
1145//---------------------------------
1146bool DGeometry::GetFDCWires(vector<vector<DFDCWire *> >&fdcwires) const{
1147 // Get geometrical information from database
1148 vector<double>z_wires;
1149 vector<double>stereo_angles;
1150
1151 if(!GetFDCZ(z_wires)) return false;
1152 if(!GetFDCStereo(stereo_angles)) return false;
1153
1154 // Get package rotation angles
1155 double ThetaX[4],ThetaY[4],ThetaZ[4];
1156 vector<double>rot_angles;
1157 Get("//posXYZ[@volume='forwardDC_package_1']/@rot", rot_angles);
1158 ThetaX[0]=rot_angles[0]*M_PI3.14159265358979323846/180.;
1159 ThetaY[0]=rot_angles[1]*M_PI3.14159265358979323846/180.;
1160 ThetaZ[0]=rot_angles[2]*M_PI3.14159265358979323846/180.;
1161 Get("//posXYZ[@volume='forwardDC_package_2']/@rot", rot_angles);
1162 ThetaX[1]=rot_angles[0]*M_PI3.14159265358979323846/180.;
1163 ThetaY[1]=rot_angles[1]*M_PI3.14159265358979323846/180.;
1164 ThetaZ[1]=rot_angles[2]*M_PI3.14159265358979323846/180.;
1165 Get("//posXYZ[@volume='forwardDC_package_3']/@rot", rot_angles);
1166 ThetaX[2]=rot_angles[0]*M_PI3.14159265358979323846/180.;
1167 ThetaY[2]=rot_angles[1]*M_PI3.14159265358979323846/180.;
1168 ThetaZ[2]=rot_angles[2]*M_PI3.14159265358979323846/180.;
1169 Get("//posXYZ[@volume='forwardDC_package_4']/@rot", rot_angles);
1170 ThetaX[3]=rot_angles[0]*M_PI3.14159265358979323846/180.;
1171 ThetaY[3]=rot_angles[1]*M_PI3.14159265358979323846/180.;
1172 ThetaZ[3]=rot_angles[2]*M_PI3.14159265358979323846/180.;
1173 // Get package offsets
1174 double dX[4],dY[4];
1175 vector<double>offsets;
1176 Get("//posXYZ[@volume='forwardDC_package_1']/@X_Y_Z",offsets);
1177 dX[0]=offsets[0];
1178 dY[0]=offsets[1];
1179 Get("//posXYZ[@volume='forwardDC_package_2']/@X_Y_Z",offsets);
1180 dX[1]=offsets[0];
1181 dY[1]=offsets[1];
1182 Get("//posXYZ[@volume='forwardDC_package_3']/@X_Y_Z",offsets);
1183 dX[2]=offsets[0];
1184 dY[2]=offsets[1];
1185 Get("//posXYZ[@volume='forwardDC_package_4']/@X_Y_Z",offsets);
1186 dX[3]=offsets[0];
1187 dY[3]=offsets[1];
1188
1189 // Get offsets tweaking nominal geometry from calibration database
1190 JCalibration * jcalib = dapp->GetJCalibration(runnumber);
1191 vector<map<string,double> >vals;
1192 vector<fdc_wire_offset_t>fdc_wire_offsets;
1193 if (jcalib->Get("FDC/wire_alignment",vals)==false){
1194 for(unsigned int i=0; i<vals.size(); i++){
1195 map<string,double> &row = vals[i];
1196
1197 // Get the offsets from the calibration database
1198 fdc_wire_offset_t temp;
1199 temp.du=row["dU"];
1200 //temp.du=0.;
1201
1202 temp.dphi=row["dPhi"];
1203 //temp.dphi=0.;
1204
1205 temp.dz=row["dZ"];
1206 // temp.dz=0.;
1207
1208 fdc_wire_offsets.push_back(temp);
1209 }
1210 }
1211
1212 vector<fdc_wire_rotation_t>fdc_wire_rotations;
1213 if (jcalib->Get("FDC/cell_rotations",vals)==false){
1214 for(unsigned int i=0; i<vals.size(); i++){
1215 map<string,double> &row = vals[i];
1216
1217 // Get the offsets from the calibration database
1218 fdc_wire_rotation_t temp;
1219 temp.dPhiX=row["dPhiX"];
1220 temp.dPhiY=row["dPhiY"];
1221 temp.dPhiZ=row["dPhiZ"];
1222
1223 fdc_wire_rotations.push_back(temp);
1224 }
1225 }
1226
1227 // Generate the vector of wire plane parameters
1228 for(int i=0; i<FDC_NUM_LAYERS24; i++){
1229 double angle=-stereo_angles[i]*M_PI3.14159265358979323846/180.+fdc_wire_offsets[i].dphi;
1230
1231 vector<DFDCWire *>temp;
1232 for(int j=0; j<WIRES_PER_PLANE96; j++){
1233 unsigned int pack_id=i/6;
1234
1235 DFDCWire *w = new DFDCWire;
1236 w->layer = i+1;
1237 w->wire = j+1;
1238 w->angle = angle;
1239
1240 // find coordinates of center of wire in rotated system
1241 float u = U_OF_WIRE_ZERO(-((96 -1)*1.0)/2) + WIRE_SPACING1.0*(float)(j);
1242 w->u=u+fdc_wire_offsets[i].du;
1243
1244 // Rotate coordinates into lab system and set the wire's origin
1245 // Note that the FDC measures "angle" such that angle=0
1246 // corresponds to the anode wire in the vertical direction
1247 // (i.e. at phi=90 degrees).
1248 float x = u*sin(angle + M_PI3.14159265358979323846/2.0);
1249 float y = u*cos(angle + M_PI3.14159265358979323846/2.0);
1250 w->origin.SetXYZ(x,y,0.);
1251 w->origin.RotateX(ThetaX[pack_id]+fdc_wire_rotations[i].dPhiX);
1252 w->origin.RotateY(ThetaY[pack_id]+fdc_wire_rotations[i].dPhiY);
1253 w->origin.RotateZ(ThetaZ[pack_id]+fdc_wire_rotations[i].dPhiZ);
1254 DVector3 globalOffsets(dX[pack_id],dY[pack_id],z_wires[i]+fdc_wire_offsets[i].dz);
1255 w->origin+=globalOffsets;
1256
1257 // Length of wire is set by active radius
1258 w->L = 2.0*sqrt(pow(FDC_ACTIVE_RADIUS48.5,2.0) - u*u);
1259
1260 // Set directions of wire's coordinate system with "udir"
1261 // along wire.
1262 w->udir.SetXYZ(sin(angle),cos(angle),0.0);
1263 w->udir.RotateX(ThetaX[pack_id]+fdc_wire_rotations[i].dPhiX);
1264 w->udir.RotateY(ThetaY[pack_id]+fdc_wire_rotations[i].dPhiY);
1265 w->udir.RotateZ(ThetaZ[pack_id]+fdc_wire_rotations[i].dPhiZ);
1266 w->angles.SetXYZ(ThetaX[pack_id]+fdc_wire_rotations[i].dPhiX,
1267 ThetaY[pack_id]+fdc_wire_rotations[i].dPhiY,
1268 ThetaZ[pack_id]+fdc_wire_rotations[i].dPhiZ);
1269 w->u+=dX[pack_id]*w->udir.y()-dY[pack_id]*w->udir.x();
1270
1271 // "s" points in direction from beamline to midpoint of
1272 // wire. This happens to be the same direction as "origin"
1273 w->sdir = w->origin;
1274 w->sdir.SetMag(1.0);
1275
1276 w->tdir = w->udir.Cross(w->sdir);
1277 w->tdir.SetMag(1.0); // This isn't really needed
1278 temp.push_back(w);
1279 }
1280 fdcwires.push_back(temp);
1281 }
1282
1283 return true;
1284}
1285
1286//---------------------------------
1287// GetFDCZ
1288//---------------------------------
1289bool DGeometry::GetFDCZ(vector<double> &z_wires) const
1290{
1291 // The FDC geometry is defined as 4 packages, each containing 2
1292 // "module"s and each of those containing 3 "chambers". The modules
1293 // are placed as multiple copies in Z using mposZ, but none of the
1294 // others are (???).
1295 //
1296 // This method is currently hardwired to assume 4 packages and
1297 // 3 chambers. (The number of modules is discovered via the
1298 // "ncopy" attribute of mposZ.)
1299
1300 vector<double> ForwardDC;
1301 vector<double> forwardDC;
1302 vector<double> forwardDC_package[4];
1303 vector<double> forwardDC_module[4];
1304 vector<double> forwardDC_chamber[4][6];
1305
1306 if(!Get("//section/composition/posXYZ[@volume='ForwardDC']/@X_Y_Z", ForwardDC)) return false;
1307 if(!Get("//composition[@name='ForwardDC']/posXYZ[@volume='forwardDC']/@X_Y_Z", forwardDC)) return false;
1308 if(!Get("//posXYZ[@volume='forwardDC_package_1']/@X_Y_Z", forwardDC_package[0])) return false;
1309 if(!Get("//posXYZ[@volume='forwardDC_package_2']/@X_Y_Z", forwardDC_package[1])) return false;
1310 if(!Get("//posXYZ[@volume='forwardDC_package_3']/@X_Y_Z", forwardDC_package[2])) return false;
1311 if(!Get("//posXYZ[@volume='forwardDC_package_4']/@X_Y_Z", forwardDC_package[3])) return false;
1312 if(!Get("//posXYZ[@volume='forwardDC_module_1']/@X_Y_Z", forwardDC_module[0])) return false;
1313 if(!Get("//posXYZ[@volume='forwardDC_module_2']/@X_Y_Z", forwardDC_module[1])) return false;
1314 if(!Get("//posXYZ[@volume='forwardDC_module_3']/@X_Y_Z", forwardDC_module[2])) return false;
1315 if(!Get("//posXYZ[@volume='forwardDC_module_4']/@X_Y_Z", forwardDC_module[3])) return false;
1316 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='1']", forwardDC_chamber[0][0])) return false;
1317 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='2']", forwardDC_chamber[0][1])) return false;
1318 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='3']", forwardDC_chamber[0][2])) return false;
1319 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='4']", forwardDC_chamber[0][3])) return false;
1320 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='5']", forwardDC_chamber[0][4])) return false;
1321 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='6']", forwardDC_chamber[0][5])) return false;
1322 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='1']", forwardDC_chamber[1][0])) return false;
1323 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='2']", forwardDC_chamber[1][1])) return false;
1324 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='3']", forwardDC_chamber[1][2])) return false;
1325 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='4']", forwardDC_chamber[1][3])) return false;
1326 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='5']", forwardDC_chamber[1][4])) return false;
1327 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='6']", forwardDC_chamber[1][5])) return false;
1328 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='1']", forwardDC_chamber[2][0])) return false;
1329 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='2']", forwardDC_chamber[2][1])) return false;
1330 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='3']", forwardDC_chamber[2][2])) return false;
1331 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='4']", forwardDC_chamber[2][3])) return false;
1332 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='5']", forwardDC_chamber[2][4])) return false;
1333 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='6']", forwardDC_chamber[2][5])) return false;
1334 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='1']", forwardDC_chamber[3][0])) return false;
1335 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='2']", forwardDC_chamber[3][1])) return false;
1336 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='3']", forwardDC_chamber[3][2])) return false;
1337 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='4']", forwardDC_chamber[3][3])) return false;
1338 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='5']", forwardDC_chamber[3][4])) return false;
1339 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='6']", forwardDC_chamber[3][5])) return false;
1340
1341 // Offset due to global FDC envelopes
1342 double zfdc = ForwardDC[2] + forwardDC[2];
1343
1344 // Loop over packages
1345 for(int package=1; package<=4; package++){
1346 double z_package = forwardDC_package[package-1][2];
1347
1348 // Each "package" has 1 "module" which is currently positioned at 0,0,0 but
1349 // that could in principle change so we add the module z-offset
1350 double z_module = forwardDC_module[package-1][2];
1351
1352 // Loop over chambers in this module
1353 for(int chamber=1; chamber<=6; chamber++){
1354 double z_chamber = forwardDC_chamber[package-1][chamber-1][2];
1355
1356 double z = zfdc + z_package + z_module + z_chamber;
1357 z_wires.push_back(z);
1358 }
1359 }
1360
1361 return true;
1362}
1363
1364//---------------------------------
1365// GetFDCStereo
1366//---------------------------------
1367bool DGeometry::GetFDCStereo(vector<double> &stereo_angles) const
1368{
1369 // The FDC geometry is defined as 4 packages, each containing 2
1370 // "module"s and each of those containing 3 "chambers". The modules
1371 // are placed as multiple copies in Z using mposZ, but none of the
1372 // others are (???).
1373 //
1374 // This method is currently hardwired to assume 4 packages and
1375 // 3 chambers. (The number of modules is discovered via the
1376 // "ncopy" attribute of mposZ.)
1377 //
1378 // Stereo angles are assumed to be rotated purely about the z-axis
1379 // and the units are not specified, but the XML currently uses degrees.
1380
1381 vector<double> forwardDC_module[4];
1382 vector<double> forwardDC_chamber[4][6];
1383
1384 if(!Get("//posXYZ[@volume='forwardDC_module_1']/@X_Y_Z", forwardDC_module[0])) return false;
1385 if(!Get("//posXYZ[@volume='forwardDC_module_2']/@X_Y_Z", forwardDC_module[1])) return false;
1386 if(!Get("//posXYZ[@volume='forwardDC_module_3']/@X_Y_Z", forwardDC_module[2])) return false;
1387 if(!Get("//posXYZ[@volume='forwardDC_module_4']/@X_Y_Z", forwardDC_module[3])) return false;
1388 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='1']", forwardDC_chamber[0][0])) return false;
1389 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='2']", forwardDC_chamber[0][1])) return false;
1390 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='3']", forwardDC_chamber[0][2])) return false;
1391 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='4']", forwardDC_chamber[0][3])) return false;
1392 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='5']", forwardDC_chamber[0][4])) return false;
1393 if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='6']", forwardDC_chamber[0][5])) return false;
1394 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='1']", forwardDC_chamber[1][0])) return false;
1395 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='2']", forwardDC_chamber[1][1])) return false;
1396 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='3']", forwardDC_chamber[1][2])) return false;
1397 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='4']", forwardDC_chamber[1][3])) return false;
1398 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='5']", forwardDC_chamber[1][4])) return false;
1399 if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='6']", forwardDC_chamber[1][5])) return false;
1400 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='1']", forwardDC_chamber[2][0])) return false;
1401 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='2']", forwardDC_chamber[2][1])) return false;
1402 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='3']", forwardDC_chamber[2][2])) return false;
1403 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='4']", forwardDC_chamber[2][3])) return false;
1404 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='5']", forwardDC_chamber[2][4])) return false;
1405 if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='6']", forwardDC_chamber[2][5])) return false;
1406 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='1']", forwardDC_chamber[3][0])) return false;
1407 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='2']", forwardDC_chamber[3][1])) return false;
1408 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='3']", forwardDC_chamber[3][2])) return false;
1409 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='4']", forwardDC_chamber[3][3])) return false;
1410 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='5']", forwardDC_chamber[3][4])) return false;
1411 if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='6']", forwardDC_chamber[3][5])) return false;
1412
1413 // Loop over packages
1414 for(int package=1; package<=4; package++){
1415
1416 // Loop over chambers
1417 for(int chamber=1; chamber<=6; chamber++){
1418 // if (chamber==4) forwardDC_chamber[package-1][chamber-1][2]+=15.0;
1419 stereo_angles.push_back(forwardDC_chamber[package-1][chamber-1][2]);
1420 }
1421 }
1422
1423 return true;
1424}
1425
1426//---------------------------------
1427// GetFDCRmin
1428//---------------------------------
1429bool DGeometry::GetFDCRmin(vector<double> &rmin_packages) const
1430{
1431 vector<double> FDA[4];
1432
1433 if(!Get("//section[@name='ForwardDC']/tubs[@name='FDA1']/@Rio_Z", FDA[0])) return false;
1434 if(!Get("//section[@name='ForwardDC']/tubs[@name='FDA2']/@Rio_Z", FDA[1])) return false;
1435 if(!Get("//section[@name='ForwardDC']/tubs[@name='FDA3']/@Rio_Z", FDA[2])) return false;
1436 if(!Get("//section[@name='ForwardDC']/tubs[@name='FDA4']/@Rio_Z", FDA[3])) return false;
1437
1438 rmin_packages.push_back(FDA[0][0]);
1439 rmin_packages.push_back(FDA[1][0]);
1440 rmin_packages.push_back(FDA[2][0]);
1441 rmin_packages.push_back(FDA[3][0]);
1442
1443 return true;
1444}
1445
1446//---------------------------------
1447// GetFDCRmax
1448//---------------------------------
1449bool DGeometry::GetFDCRmax(double &rmax_active_fdc) const
1450{
1451 // We assume that all packages have the same outer radius of the
1452 // active area.
1453 vector<double> FDA1;
1454
1455 bool good = Get("//section[@name='ForwardDC']/tubs[@name='FDA1']/@Rio_Z", FDA1);
1456
1457 if(!good){
1458 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1458<<" "
<<"Unable to retrieve FDC Rmax values."<<endl;
1459 return good;
1460 }
1461
1462 rmax_active_fdc = FDA1[1];
1463
1464 return good;
1465}
1466
1467//---------------------------------
1468// GetCDCOption
1469//---------------------------------
1470bool DGeometry::GetCDCOption(string &cdc_option) const
1471{
1472 bool good = Get("//section[@name='CentralDC_s']/composition/posXYZ/@volume", cdc_option);
1473
1474 if(!good){
1475 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1475<<" "
<<"Unable to retrieve CDC option string."<<endl;
1476 }
1477
1478 return good;
1479}
1480
1481//---------------------------------
1482// GetCDCCenterZ
1483//---------------------------------
1484bool DGeometry::GetCDCCenterZ(double &cdc_center_z) const
1485{
1486
1487 return false;
1488}
1489
1490//---------------------------------
1491// GetCDCAxialLength
1492//---------------------------------
1493bool DGeometry::GetCDCAxialLength(double &cdc_axial_length) const
1494{
1495 vector<double> Rio_Z;
1496 bool good = Get("//section[@name='CentralDC']/tubs[@name='STRW']/@Rio_Z", Rio_Z);
1497 cdc_axial_length = Rio_Z[2];
1498
1499 if(!good){
1500 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1500<<" "
<<"Unable to retrieve CDC axial wire length"<<endl;
1501 }
1502
1503 return false;
1504}
1505
1506//---------------------------------
1507// GetCDCStereo
1508//---------------------------------
1509bool DGeometry::GetCDCStereo(vector<double> &cdc_stereo) const
1510{
1511
1512 return false;
1513}
1514
1515//---------------------------------
1516// GetCDCRmid
1517//---------------------------------
1518bool DGeometry::GetCDCRmid(vector<double> &cdc_rmid) const
1519{
1520
1521 return false;
1522}
1523
1524//---------------------------------
1525// GetCDCNwires
1526//---------------------------------
1527bool DGeometry::GetCDCNwires(vector<int> &cdc_nwires) const
1528{
1529 cdc_nwires.push_back(42);
1530 cdc_nwires.push_back(42);
1531 cdc_nwires.push_back(54);
1532 cdc_nwires.push_back(54);
1533 cdc_nwires.push_back(66);
1534 cdc_nwires.push_back(66);
1535 cdc_nwires.push_back(80);
1536 cdc_nwires.push_back(80);
1537 cdc_nwires.push_back(93);
1538 cdc_nwires.push_back(93);
1539 cdc_nwires.push_back(106);
1540 cdc_nwires.push_back(106);
1541 cdc_nwires.push_back(123);
1542 cdc_nwires.push_back(123);
1543 cdc_nwires.push_back(135);
1544 cdc_nwires.push_back(135);
1545 cdc_nwires.push_back(146);
1546 cdc_nwires.push_back(146);
1547 cdc_nwires.push_back(158);
1548 cdc_nwires.push_back(158);
1549 cdc_nwires.push_back(170);
1550 cdc_nwires.push_back(170);
1551 cdc_nwires.push_back(182);
1552 cdc_nwires.push_back(182);
1553 cdc_nwires.push_back(197);
1554 cdc_nwires.push_back(197);
1555 cdc_nwires.push_back(209);
1556 cdc_nwires.push_back(209);
1557
1558 return false;
1559}
1560
1561
1562//---------------------------------
1563// GetCDCEndplate
1564//---------------------------------
1565bool DGeometry::GetCDCEndplate(double &z,double &dz,double &rmin,double &rmax)
1566 const{
1567
1568 vector<double>cdc_origin;
1569 vector<double>cdc_center;
1570 vector<double>cdc_layers_offset;
1571 vector<double>cdc_endplate_pos;
1572 vector<double>cdc_endplate_dim;
1573
1574 if(!Get("//posXYZ[@volume='CentralDC'/@X_Y_Z",cdc_origin)) return false;
1575 if(!Get("//posXYZ[@volume='centralDC']/@X_Y_Z",cdc_center)) return false;
1576 if(!Get("//posXYZ[@volume='CDPD']/@X_Y_Z",cdc_endplate_pos)) return false;
1577 if(!Get("//tubs[@name='CDPD']/@Rio_Z",cdc_endplate_dim)) return false;
1578 if(!Get("//posXYZ[@volume='CDClayers']/@X_Y_Z",cdc_layers_offset)) return false;
1579
1580 if(cdc_origin.size()<3){
1581 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1581<<" "
<<"cdc_origin.size()<3 !"<<endl;
1582 return false;
1583 }
1584 if(cdc_center.size()<3){
1585 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1585<<" "
<<"cdc_center.size()<3 !"<<endl;
1586 return false;
1587 }
1588 if(cdc_endplate_pos.size()<3){
1589 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1589<<" "
<<"cdc_endplate_pos.size()<3 !"<<endl;
1590 return false;
1591 }
1592 if(cdc_endplate_dim.size()<3){
1593 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1593<<" "
<<"cdc_endplate_dim.size()<3 !"<<endl;
1594 return false;
1595 }
1596 if (cdc_layers_offset.size()<3){
1597 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1597<<" "
<<"cdc_layers_offset.size()<3 !"<<endl;
1598 return false;
1599 }
1600
1601 z=cdc_origin[2]+cdc_center[2]+cdc_endplate_pos[2]+cdc_layers_offset[2];
1602 dz=cdc_endplate_dim[2];
1603 rmin=cdc_endplate_dim[0];
1604 rmax=cdc_endplate_dim[1];
1605
1606 return true;
1607 }
1608//---------------------------------
1609// GetBCALRmin
1610//---------------------------------
1611// Including the support plate
1612bool DGeometry::GetBCALRmin(float &bcal_rmin) const
1613{
1614 vector<float> bcal_mother_Rio_Z;
1615 bool good = Get("//section[@name='BarrelEMcal']/tubs[@name='BCAL']/@Rio_Z", bcal_mother_Rio_Z);
1616 if(!good){
1617 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1617<<" "
<<"Unable to retrieve BCAL mother RioZ info."<<endl;
1618 bcal_rmin = 0.0;
1619 return false;
1620 }
1621 if(bcal_mother_Rio_Z.size() == 3){
1622 bcal_rmin = bcal_mother_Rio_Z[0];
1623 return true;
1624 }
1625 else{
1626 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1626<<" "
<<"Wrong vector size for BCAL mother RioZ!!!"<<endl;
1627 bcal_rmin = 0.0;
1628 return false;
1629 }
1630}
1631
1632//---------------------------------
1633// GetBCALfADCRadii
1634//---------------------------------
1635bool DGeometry::GetBCALfADCRadii(vector<float> &fADC_radii) const
1636{
1637 vector<float> BM[5];
1638
1639 if(!Get("//section[@name='BarrelEMcal']/tubs[@name='BM01']/@Rio_Z", BM[0])) return false;
1640 if(!Get("//section[@name='BarrelEMcal']/tubs[@name='BM02']/@Rio_Z", BM[1])) return false;
1641 if(!Get("//section[@name='BarrelEMcal']/tubs[@name='BM04']/@Rio_Z", BM[2])) return false;
1642 if(!Get("//section[@name='BarrelEMcal']/tubs[@name='BMF7']/@Rio_Z", BM[3])) return false;
1643 if(!Get("//section[@name='BarrelEMcal']/tubs[@name='BMFA']/@Rio_Z", BM[4])) return false;
1644
1645 fADC_radii.push_back(BM[0][0]);
1646 fADC_radii.push_back(BM[1][0]);
1647 fADC_radii.push_back(BM[2][0]);
1648 fADC_radii.push_back(BM[3][0]);
1649 fADC_radii.push_back(BM[4][1]);
1650
1651 return true;
1652}
1653
1654//---------------------------------
1655// GetBCALNmodules
1656//---------------------------------
1657bool DGeometry::GetBCALNmodules(unsigned int &bcal_nmodules) const
1658{
1659 vector<unsigned int> ncopy;
1660 bool good = Get("//section[@name='BarrelEMcal']/composition/mposPhi/@ncopy", ncopy);
1661 if(!good){
1662 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1662<<" "
<<"Unable to retrieve BCAL barrelModule ncopy info."<<endl;
1663 bcal_nmodules = 0;
1664 return false;
1665 }
1666 if(ncopy.size() == 1){
1667 bcal_nmodules = ncopy[0];
1668 return true;
1669 }else{
1670 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1670<<" "
<<"Wrong vector size for BCAL barrelModule ncopy!!!"<<endl;
1671 bcal_nmodules = 0;
1672 return false;
1673 }
1674}
1675
1676//---------------------------------
1677// GetBCALCenterZ
1678//---------------------------------
1679bool DGeometry::GetBCALCenterZ(float &bcal_center_z) const
1680{
1681 vector<float> z0;
1682 bool good = Get("//section[@name='BarrelEMcal']/parameters/real[@name='z0']/@value", z0);
1683 if(!good){
1684 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1684<<" "
<<"Unable to retrieve BCAL parameters z0 info."<<endl;
1685 bcal_center_z = 0.0;
1686 return false;
1687 }
1688 if(z0.size() == 1){
1689 bcal_center_z = z0[0];
1690 return true;
1691 }else{
1692 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1692<<" "
<<"Wrong vector size for BCAL parameters z0!!!"<<endl;
1693 bcal_center_z = 0.0;
1694 return false;
1695 }
1696
1697}
1698
1699//---------------------------------
1700// GetBCALLength
1701//---------------------------------
1702// The lightguides are not included
1703bool DGeometry::GetBCALLength(float &bcal_length) const
1704{
1705 vector<float> module_length;
1706 bool good = Get("//section[@name='BarrelEMcal']/tubs[@name='BM01']/@Rio_Z", module_length);
1707 if(!good){
1708 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1708<<" "
<<"Unable to retrieve BCAL submodule RioZ info."<<endl;
1709 bcal_length = 0.0;
1710 return false;
1711 }
1712 if(module_length.size() == 3){
1713 bcal_length = module_length[2];
1714 return true;
1715 }
1716 else{
1717 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1717<<" "
<<"Wrong vector size for BCAL submodule RioZ!!!"<<endl;
1718 bcal_length = 0.0;
1719 return false;
1720 }
1721}
1722
1723//---------------------------------
1724// GetBCALDepth
1725//---------------------------------
1726// Including the support plate and the support bar
1727bool DGeometry::GetBCALDepth(float &bcal_depth) const
1728{
1729 vector<float> bcal_moth_Rio_Z;
1730 bool good = Get("//section[@name='BarrelEMcal']/tubs[@name='BCAL']/@Rio_Z", bcal_moth_Rio_Z);
1731 if(!good){
1732 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1732<<" "
<<"Unable to retrieve BCAL mother RioZ info."<<endl;
1733 bcal_depth = 0.0;
1734 return false;
1735 }
1736 if(bcal_moth_Rio_Z.size() == 3){
1737 bcal_depth = bcal_moth_Rio_Z[1] - bcal_moth_Rio_Z[0];
1738 return true;
1739 }
1740 else{
1741 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1741<<" "
<<"Wrong vector size for BCAL mother RioZ!!!"<<endl;
1742 bcal_depth = 0.0;
1743 return false;
1744 }
1745
1746}
1747
1748//---------------------------------
1749// GetBCALPhiShift
1750//---------------------------------
1751bool DGeometry::GetBCALPhiShift(float &bcal_phi_shift) const
1752{
1753 vector<float> Phi0;
1754 bool good = Get("//section[@name='BarrelEMcal']/composition/mposPhi/@Phi0", Phi0);
1755 if(!good) return false;
1756 if(Phi0.size() == 1){
1757 bcal_phi_shift = Phi0[0];
1758 return true;
1759 }else{
1760 bcal_phi_shift = 0.0;
1761 return false;
1762 }
1763}
1764
1765//---------------------------------
1766// GetCCALZ
1767//---------------------------------
1768bool DGeometry::GetCCALZ(double &z_ccal) const
1769{
1770 vector<double> ComptonEMcalpos;
1771 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1772 bool good = Get("//section/composition/posXYZ[@volume='ComptonEMcal']/@X_Y_Z", ComptonEMcalpos);\
1773 jgeom->SetVerbose(1); // reenable error messages
1774
1775 if(!good){
1776 // NEED TO RETHINK ERROR REPORTING FOR OPTIONAL DETECTOR ELEMENTS
1777 //_DBG_<<"Unable to retrieve ComptonEMcal position."<<endl;
1778 z_ccal = 1279.376;
1779 return false;
1780 }else{
1781 z_ccal = ComptonEMcalpos[2];
1782 return true;
1783 }
1784}
1785
1786//---------------------------------
1787// GetFCALZ
1788//---------------------------------
1789bool DGeometry::GetFCALZ(double &z_fcal) const
1790{
1791 vector<double> ForwardEMcalpos;
1792 bool good = Get("//section/composition/posXYZ[@volume='ForwardEMcal']/@X_Y_Z", ForwardEMcalpos);
1793
1794 if(!good){
1795 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1795<<" "
<<"Unable to retrieve ForwardEMcal position."<<endl;
1796 z_fcal=0.0;
1797 return false;
1798 }else{
1799 z_fcal = ForwardEMcalpos[2];
1800 return true;
1801 }
1802}
1803
1804
1805//---------------------------------
1806// GetFCALPosition
1807//---------------------------------
1808bool DGeometry::GetFCALPosition(double &x,double &y,double &z) const
1809{
1810 vector<double> ForwardEMcalpos;
1811 bool good = Get("//section/composition/posXYZ[@volume='ForwardEMcal']/@X_Y_Z", ForwardEMcalpos);
1812
1813 if(!good){
1814 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1814<<" "
<<"Unable to retrieve ForwardEMcal position."<<endl;
1815 x=0.,y=0.,z=0.;
1816 return false;
1817 }else{
1818 x=ForwardEMcalpos[0],y=ForwardEMcalpos[1],z=ForwardEMcalpos[2];
1819 //_DBG_ << "FCAL position: (x,y,z)=(" << x <<"," << y << "," << z << ")"<<endl;
1820 return true;
1821 }
1822}
1823
1824//---------------------------------
1825// GetCCALPosition
1826//---------------------------------
1827bool DGeometry::GetCCALPosition(double &x,double &y,double &z) const
1828{
1829 vector<double> ComptonEMcalpos;
1830 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1831 bool good = Get("//section/composition/posXYZ[@volume='ComptonEMcal']/@X_Y_Z", ComptonEMcalpos);
1832 jgeom->SetVerbose(1); // reenable error messages
1833
1834 if(!good){
1835 //_DBG_<<"Unable to retrieve ComptonEMcal position."<<endl;
1836 x=0.,y=0.,z=0.;
1837 return false;
1838 }else{
1839 x=ComptonEMcalpos[0],y=ComptonEMcalpos[1],z=ComptonEMcalpos[2];
1840 //_DBG_ << "CCAL position: (x,y,z)=(" << ComptonEMcalpos[0] <<","
1841 // << ComptonEMcalpos[1]<<","<<ComptonEMcalpos[2]<< ")" << endl;
1842 return true;
1843 }
1844}
1845
1846//---------------------------------
1847// GetFCALInsertRowSize
1848//---------------------------------
1849bool DGeometry::GetFCALInsertRowSize(int &insert_row_size) const
1850{
1851 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1852 bool good = Get("//composition[@name='LeadTungstateFullRow']/mposX[@volume='LTBLwrapped']/@ncopy",insert_row_size);
1853 jgeom->SetVerbose(1); // reenable error messages
1854
1855 if(!good){
1856 // NEED TO RETHINK ERROR REPORTING FOR OPTIONAL DETECTOR ELEMENTS
1857 //_DBG_<<"Unable to retrieve ComptonEMcal position."<<endl;
1858 insert_row_size = 0;
1859 return false;
1860 }else{
1861 return true;
1862 }
1863}
1864
1865//---------------------------------
1866// GetFCALBlockSize
1867//---------------------------------
1868bool DGeometry::GetFCALBlockSize(vector<double> &block) const
1869{
1870 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1871 bool good = Get("//box[@name='LGBL']/@X_Y_Z",block);
1872 jgeom->SetVerbose(1); // reenable error messages
1873
1874 if(!good){
1875 // NEED TO RETHINK ERROR REPORTING FOR OPTIONAL DETECTOR ELEMENTS
1876 //_DBG_<<"Unable to retrieve ComptonEMcal position."<<endl;
1877 return false;
1878 }else{
1879 return true;
1880 }
1881}
1882
1883//---------------------------------
1884// GetFCALInsertBlockSize
1885//---------------------------------
1886bool DGeometry::GetFCALInsertBlockSize(vector<double> &block) const
1887{
1888 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1889 bool good = Get("//box[@name='LTB1']/@X_Y_Z",block);
1890 jgeom->SetVerbose(1); // reenable error messages
1891
1892 if(!good){
1893 // NEED TO RETHINK ERROR REPORTING FOR OPTIONAL DETECTOR ELEMENTS
1894 //_DBG_<<"Unable to retrieve ComptonEMcal position."<<endl;
1895 return false;
1896 }else{
1897 return true;
1898 }
1899}
1900
1901//---------------------------------
1902// GetDIRCZ
1903//---------------------------------
1904bool DGeometry::GetDIRCZ(double &z_dirc) const
1905{
1906 vector<double> dirc_face;
1907 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1908 bool good = Get("//section/composition/posXYZ[@volume='DIRC']/@X_Y_Z",dirc_face);
1909 jgeom->SetVerbose(1); // reenable error messages
1910
1911 if(!good){
1912 //_DBG_<<"Unable to retrieve DIRC position."<<endl;
1913 z_dirc=0.0;
1914 return false;
1915 }
1916 else{
1917 vector<double>dirc_plane;
1918 vector<double>dirc_shift;
1919 vector<double>bar_plane;
1920 Get("//composition[@name='DRCC']/posXYZ[@volume='DCML10']/@X_Y_Z/plane[@value='1']", dirc_plane);
1921 Get("//composition[@name='DIRC']/posXYZ[@volume='DRCC']/@X_Y_Z", dirc_shift);
1922 z_dirc=dirc_face[2]+dirc_plane[2]+dirc_shift[2] + 0.8625; // last shift is the average center of quartz bar (585.862)
1923
1924 //jout << "DIRC z position = " << z_dirc << " cm." << endl;
1925 return true;
1926 }
1927}
1928
1929//---------------------------------
1930// GetTRDZ
1931//---------------------------------
1932bool DGeometry::GetTRDZ(vector<double> &z_trd) const
1933{
1934 vector<double> trd_origin;
1935 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1936 bool good = Get("//section/composition/posXYZ[@volume='TRDGEM']/@X_Y_Z",trd_origin);
1937 jgeom->SetVerbose(1); // reenable error messages
1938
1939 if(!good){
1940 //_DBG_<<"Unable to retrieve TRD position."<<endl;
1941 return false;
1942 }
1943 else{
1944 vector<double>trd_G10;
1945 Get("//composition[@name='TRDGEM']/posXYZ[@volume='TGPK']/@X_Y_Z",trd_G10);
1946
1947 jout << "TRD z positions = ";
1948 for(int i=0; i<5; i++) {
1949 vector<double>trd_plane;
1950 Get(Form("//composition[@name='TGPK']/posXYZ[@volume='TRDG']/@X_Y_Z/plane[@value='%d']",i),trd_plane);
1951 double z_trd_plane=trd_origin[2]+trd_G10[2]+trd_plane[2];
1952 jout << z_trd_plane << ", ";
1953 z_trd.push_back(z_trd_plane);
1954 }
1955 jout << "cm" << endl;
1956 }
1957
1958 return true;
1959}
1960
1961//---------------------------------
1962// GetTOFZ
1963//---------------------------------
1964bool DGeometry::GetTOFZ(vector<double> &z_tof) const
1965{
1966 vector<double> ForwardTOF;
1967 vector<double> forwardTOF[2];
1968 vector<double> FTOC;
1969
1970 if(!Get("//section/composition/posXYZ[@volume='ForwardTOF']/@X_Y_Z", ForwardTOF)) return false;
1971 if(!Get("//composition[@name='ForwardTOF']/posXYZ[@volume='forwardTOF']/@X_Y_Z/plane[@value='0']", forwardTOF[0])) return false;
1972 if(!Get("//composition[@name='ForwardTOF']/posXYZ[@volume='forwardTOF']/@X_Y_Z/plane[@value='1']", forwardTOF[1])) return false;
1973 if(!Get("//box[@name='FTOC' and sensitive='true']/@X_Y_Z", FTOC)) return false;
1974
1975 z_tof.push_back(ForwardTOF[2] + forwardTOF[0][2] - FTOC[2]/2.0);
1976 z_tof.push_back(ForwardTOF[2] + forwardTOF[1][2] - FTOC[2]/2.0);
1977
1978 //cerr << "DGeometry::GetTOFZ() = " << z_tof[0] << " " << z_tof[1] << endl;
1979
1980 return true;
1981}
1982
1983//---------------------------------
1984// GetTOFPaddleParameters
1985//---------------------------------
1986bool DGeometry::GetTOFPaddleParameters(map<string,double> &paddle_params) const
1987{
1988 vector<double> xyz_bar;
1989
1990 // load the number of bars in each area
1991 int num_bars1 = 0;
1992 if(!Get("//composition[@name='forwardTOF_bottom1']/mposY[@volume='FTOC']/@ncopy",num_bars1)) return false;
1993 int num_narrow_bars1 = 0;
1994 if(!Get("//composition[@name='forwardTOF_bottom2']/mposY[@volume='FTOX']/@ncopy",num_narrow_bars1)) return false;
1995 int num_single_end_bars1 = 0;
1996 if(!Get("//composition[@name='forwardTOF_north']/mposY[@volume='FTOH']/@ncopy",num_single_end_bars1)) return false;
1997
1998 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1999 int num_narrower_bars1 = 0; // optional - added during upgrade
2000 Get("//composition[@name='forwardTOF_bottom3']/mposY[@volume='FTOL']/@ncopy",num_narrower_bars1);
2001 int num_narrower_bars2 = 0; // optional - added during upgrade
2002 Get("//composition[@name='forwardTOF_top3']/mposY[@volume='FTOL']/@ncopy",num_narrower_bars2);
2003 jgeom->SetVerbose(1); // reenable error messages
2004
2005 int num_narrow_bars2 = 0;
2006 if(!Get("//composition[@name='forwardTOF_top2']/mposY[@volume='FTOX']/@ncopy",num_narrow_bars2)) return false;
2007 int num_bars2 = 0;
2008 if(!Get("//composition[@name='forwardTOF_top1']/mposY[@volume='FTOC']/@ncopy",num_bars2)) return false;
2009 int num_single_end_bars2 = 0;
2010 if(!Get("//composition[@name='forwardTOF_south']/mposY[@volume='FTOH']/@ncopy",num_single_end_bars2)) return false;
2011
2012 int NLONGBARS = num_bars1 + num_bars2 + num_narrow_bars1 + num_narrow_bars2
2013 + num_narrower_bars1 + num_narrower_bars2;
2014 int NSHORTBARS = num_single_end_bars1 + num_single_end_bars2;
2015 int FIRSTSHORTBAR = num_bars1 + num_narrow_bars1 + num_narrower_bars1 + 1;
2016 int LASTSHORTBAR = FIRSTSHORTBAR + NSHORTBARS/2 - 1;
2017
2018 // load bar sizes
2019 //Get("//composition[@name='forwardTOF_bottom1']/mposY[@volume='FTOC']/@X_Y_Z",xyz_bar);
2020 if(!Get("//box[@name='FTOC' and sensitive='true']/@X_Y_Z", xyz_bar)) return false;
2021 double LONGBARLENGTH = xyz_bar[0];
2022 double BARWIDTH = xyz_bar[1];
2023 //Get("//composition[@name='forwardTOF_bottom1']/mposY[@volume='FTOH']/@X_Y_Z",xyz_bar);
2024 if(!Get("//box[@name='FTOH' and sensitive='true']/@X_Y_Z", xyz_bar)) return false;
2025 double SHORTBARLENGTH = xyz_bar[0];
2026
2027
2028 // load up the structure containing the parameters for the calling function
2029 paddle_params["NLONGBARS"] = NLONGBARS;
2030 paddle_params["NSHORTBARS"] = NSHORTBARS;
2031 paddle_params["BARWIDTH"] = BARWIDTH;
2032
2033 paddle_params["LONGBARLENGTH"] = LONGBARLENGTH;
2034 paddle_params["HALFLONGBARLENGTH"] = LONGBARLENGTH/2.;
2035 paddle_params["SHORTBARLENGTH"] = SHORTBARLENGTH;
2036 paddle_params["HALFSHORTBARLENGTH"] = SHORTBARLENGTH/2.;
2037
2038 paddle_params["FIRSTSHORTBAR"] = FIRSTSHORTBAR;
2039 paddle_params["LASTSHORTBAR"] = LASTSHORTBAR;
2040
2041 //cout << "In DGeometry::GetTOFPaddleParameters() ..." << endl;
2042 //for(auto el : paddle_params) {
2043 // std::cout << el.first << " " << el.second << endl;
2044 //}
2045
2046 return true;
2047}
2048
2049
2050//---------------------------------
2051// GetTOFPaddlePerpPositions
2052//---------------------------------
2053bool DGeometry::GetTOFPaddlePerpPositions(vector<double> &y_tof, vector<double> &y_widths) const
2054{
2055 // add in a dummy entry, since we are indexing by paddle number, which starts at 1
2056 // maybe change this some day?
2057 y_tof.push_back(0);
2058 y_widths.push_back(0);
2059
2060 // Next fill array of bar positions within a plane
2061 // y_tof[barnumber] gives y position in the center of the bar. [currently barnumber = 1 - 46]
2062 double y0,dy;
1
'y0' declared without an initial value
2063
2064 // load the number of bars
2065 int num_bars=1; // start counting at 1
2066 int num_bars1 = 0;
2067 Get("//composition[@name='forwardTOF_bottom1']/mposY[@volume='FTOC']/@ncopy",num_bars1);
2068 int num_narrow_bars1 = 0;
2069 Get("//composition[@name='forwardTOF_bottom2']/mposY[@volume='FTOX']/@ncopy",num_narrow_bars1);
2070 int num_single_end_bars1 = 0;
2071 Get("//composition[@name='forwardTOF_north']/mposY[@volume='FTOH']/@ncopy",num_single_end_bars1);
2072
2073 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2074 int num_narrower_bars1 = 0;
2075 Get("//composition[@name='forwardTOF_bottom3']/mposY[@volume='FTOL']/@ncopy",num_narrower_bars1);
2076 int num_narrower_bars2 = 0;
2077 Get("//composition[@name='forwardTOF_top3']/mposY[@volume='FTOL']/@ncopy",num_narrower_bars2);
2078 jgeom->SetVerbose(1); // reenable error messages
2079
2080 int num_narrow_bars2 = 0;
2081 Get("//composition[@name='forwardTOF_top2']/mposY[@volume='FTOX']/@ncopy",num_narrow_bars2);
2082 int num_bars2 = 0;
2083 Get("//composition[@name='forwardTOF_top1']/mposY[@volume='FTOC']/@ncopy",num_bars2);
2084 int num_single_end_bars2 = 0;
2085 Get("//composition[@name='forwardTOF_south']/mposY[@volume='FTOH']/@ncopy",num_single_end_bars2);
2086
2087 // First 19 long bars
2088 Get("//composition[@name='forwardTOF_bottom1']/mposY/@Y0",y0);
2
Calling 'DGeometry::Get'
9
Returning from 'DGeometry::Get'
2089 Get("//composition[@name='forwardTOF_bottom1']/mposY/@dY",dy);
2090 vector<double>tof_bottom1;
2091 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_bottom1']/@X_Y_Z",tof_bottom1);
2092 for (int k=num_bars;k<num_bars+num_bars1;k++){
10
Assuming the condition is true
11
Loop condition is true. Entering loop body
2093 y_tof.push_back(y0+tof_bottom1[1]+dy*double(k-num_bars));
12
The left operand of '+' is a garbage value
2094 y_widths.push_back(dy);
2095 }
2096 num_bars+=num_bars1;
2097
2098 // two narrow long bars
2099 Get("//composition[@name='forwardTOF_bottom2']/mposY/@Y0",y0);
2100 Get("//composition[@name='forwardTOF_bottom2']/mposY/@dY",dy);
2101 vector<double>tof_bottom2;
2102 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_bottom2']/@X_Y_Z",tof_bottom2);
2103 for (int k=num_bars;k<num_bars+num_narrow_bars1;k++){
2104 y_tof.push_back(y0+tof_bottom2[1]+dy*double(k-num_bars));
2105 y_widths.push_back(dy);
2106 }
2107 num_bars+=num_narrow_bars1;
2108
2109 // two narrower long bars - added by upgrade
2110 if(num_narrower_bars1 > 0) {
2111 Get("//composition[@name='forwardTOF_bottom3']/mposY/@Y0",y0);
2112 Get("//composition[@name='forwardTOF_bottom3']/mposY/@dY",dy);
2113 vector<double>tof_bottom3;
2114 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_bottom3']/@X_Y_Z",tof_bottom3);
2115 for (int k=num_bars;k<num_bars+num_narrower_bars1;k++){
2116 y_tof.push_back(y0+tof_bottom3[1]+dy*double(k-num_bars));
2117 y_widths.push_back(dy);
2118 }
2119 num_bars+=num_narrow_bars1;
2120 }
2121
2122 // two short wide bars (4 wide in upgrade)
2123 Get("//composition[@name='forwardTOF_north']/mposY/@Y0",y0);
2124 Get("//composition[@name='forwardTOF_north']/mposY/@dY",dy);
2125 vector<double>tof_north;
2126 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_north']/@X_Y_Z",tof_north);
2127 for (int k=num_bars;k<num_bars+num_single_end_bars1;k++){
2128 y_tof.push_back(y0+tof_north[1]+dy*double(k-num_bars));
2129 y_widths.push_back(dy);
2130 }
2131 num_bars+=num_single_end_bars1;
2132
2133 // two narrower long bars - added by upgrade
2134 if(num_narrower_bars2 > 0) {
2135 Get("//composition[@name='forwardTOF_top3']/mposY/@Y0",y0);
2136 Get("//composition[@name='forwardTOF_top3']/mposY/@dY",dy);
2137 vector<double>tof_top3;
2138 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_top3']/@X_Y_Z",tof_top3);
2139 for (int k=num_bars;k<num_bars+num_narrower_bars2;k++){
2140 y_tof.push_back(y0+tof_top3[1]+dy*double(k-num_bars));
2141 y_widths.push_back(dy);
2142 }
2143 num_bars+=num_narrow_bars2;
2144 }
2145
2146 // two narrow long bars
2147 Get("//composition[@name='forwardTOF_top2']/mposY/@Y0",y0);
2148 Get("//composition[@name='forwardTOF_top2']/mposY/@dY",dy);
2149 vector<double>tof_top2;
2150 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_top2']/@X_Y_Z",tof_top2);
2151 for (int k=num_bars;k<num_bars+num_narrow_bars2;k++){
2152 y_tof.push_back(y0+tof_top2[1]+dy*double(k-num_bars));
2153 y_widths.push_back(dy);
2154 }
2155 num_bars+=num_narrow_bars2;
2156
2157 // Last 19 long bars
2158 Get("//composition[@name='forwardTOF_top1']/mposY/@Y0",y0);
2159 Get("//composition[@name='forwardTOF_top1']/mposY/@dY",dy);
2160 vector<double>tof_top1;
2161 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_top1']/@X_Y_Z",tof_top1);
2162 for (int k=num_bars;k<num_bars+num_bars2;k++){
2163 y_tof.push_back(y0+tof_top1[1]+dy*double(k-num_bars));
2164 y_widths.push_back(dy);
2165 }
2166 num_bars+=num_bars2;
2167
2168 /*
2169 // two more short wide bars - IGNORE FOR NOW, ASSUME SAME Y AS OTHER SINGLE ENDED
2170 Get("//composition[@name='forwardTOF_south']/mposY/@Y0",y0);
2171 Get("//composition[@name='forwardTOF_south']/mposY/@dY",dy);
2172 vector<double>tof_south;
2173 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_south']/@X_Y_Z",tof_south);
2174 for (unsigned int k=45;k<47;k++){
2175 y_tof.push_back(y0+tof_south[1]+dy*double(k-45));
2176 }
2177 */
2178
2179 return true;
2180}
2181
2182//---------------------------------
2183// GetTargetZ
2184//---------------------------------
2185bool DGeometry::GetTargetZ(double &z_target) const
2186{
2187 // Default to nominal center of GlueX target
2188 z_target=65.;
2189
2190 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2191
2192 // Check GlueX target is defined
2193 bool gluex_target_exists = true;
2194 vector<double> xyz_vessel;
2195 vector<double> xyz_target;
2196 vector<double> xyz_detector;
2197 if(gluex_target_exists) gluex_target_exists = Get("//composition[@name='targetVessel']/posXYZ[@volume='targetTube']/@X_Y_Z", xyz_vessel);
2198 if(gluex_target_exists) gluex_target_exists = Get("//composition[@name='Target']/posXYZ[@volume='targetVessel']/@X_Y_Z", xyz_target);
2199 if(gluex_target_exists) gluex_target_exists = Get("//posXYZ[@volume='Target']/@X_Y_Z", xyz_detector);
2200 if(gluex_target_exists) {
2201 z_target = xyz_vessel[2] + xyz_target[2] + xyz_detector[2];
2202 jgeom->SetVerbose(1); // reenable error messages
2203 return true;
2204 }
2205
2206 // Check if CPP target is defined
2207 bool cpp_target_exists = true;
2208 vector<double> xyz_TGT0;
2209 vector<double> xyz_TARG;
2210 vector<double> xyz_TargetCPP;
2211 if(cpp_target_exists) cpp_target_exists = Get("//composition/posXYZ[@volume='TGT0']/@X_Y_Z", xyz_TGT0);
2212 if(cpp_target_exists) cpp_target_exists = Get("//composition/posXYZ[@volume='TARG']/@X_Y_Z", xyz_TARG);
2213 if(cpp_target_exists) cpp_target_exists = Get("//composition/posXYZ[@volume='TargetCPP']/@X_Y_Z", xyz_TargetCPP);
2214 if(cpp_target_exists) {
2215 z_target = xyz_TGT0[2] + xyz_TARG[2] + xyz_TargetCPP[2];
2216 jgeom->SetVerbose(1); // reenable error messages
2217 return true;
2218 }
2219
2220 // Check if PrimEx Be target is defined
2221 bool primex_target_exists = true;
2222 vector<double> xyz_BETG;
2223 if(primex_target_exists) primex_target_exists = Get("//composition[@name='targetVessel']/posXYZ[@volume='BETG']/@X_Y_Z", xyz_BETG);
2224 if(primex_target_exists) primex_target_exists = Get("//composition[@name='Target']/posXYZ[@volume='targetVessel']/@X_Y_Z", xyz_target);
2225 if(primex_target_exists) primex_target_exists = Get("//posXYZ[@volume='Target']/@X_Y_Z", xyz_detector);
2226 if(primex_target_exists) {
2227
2228 z_target = xyz_BETG[2] + xyz_target[2] + xyz_detector[2];
2229
2230 // cout << " PrimEx Be targer selected. Z target = = " << z_target << endl;
2231
2232 jgeom->SetVerbose(1); // reenable error messages
2233 return true;
2234 }
2235
2236
2237
2238 jout << " WARNING: Unable to get target location from XML for any of GlueX, PrimEx, or CPP targets. It's likely an empty target run. Using default of " <<
2239 z_target << " cm" << endl;
2240
2241 jgeom->SetVerbose(1); // reenable error messages
2242
2243 return false;
2244}
2245
2246//---------------------------------
2247// GetTargetLength
2248//---------------------------------
2249bool DGeometry::GetTargetLength(double &target_length) const
2250{
2251 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2252 vector<double> zLength;
2253 bool good = Get("//section[@name='Target']/pcon[@name='LIH2']/real[@name='length']/[@value]", zLength);
2254 jgeom->SetVerbose(1); // reenable error messages
2255
2256 target_length = good ? zLength[0]:0.0;
2257
2258 return good;
2259}
2260
2261// Get vectors of positions and norm vectors for start counter from XML
2262bool DGeometry::GetStartCounterGeom(vector<vector<DVector3> >&pos,
2263 vector<vector<DVector3> >&norm
2264 ) const
2265{
2266
2267 JCalibration *jcalib = dapp->GetJCalibration(runnumber);
2268
2269 // Check if Start Counter geometry is present
2270 vector<double> sc_origin;
2271 bool got_sc = Get("//posXYZ[@volume='StartCntr']/@X_Y_Z", sc_origin);
2272 if(got_sc){
2273 // Offset from beam center
2274 vector<double>sc_origin_delta;
2275 Get("//posXYZ[@volume='startCntr']/@X_Y_Z", sc_origin_delta);
2276 double dx=sc_origin_delta[0];
2277 double dy=sc_origin_delta[1];
2278
2279 // z-position at upstream face of scintillators.
2280 double z0=sc_origin[2];
2281
2282 // Get rotation angles
2283 vector<double>sc_rot_angles;
2284 Get("//posXYZ[@volume='startCntr']/@rot", sc_rot_angles);
2285 double ThetaX=sc_rot_angles[0]*M_PI3.14159265358979323846/180.;
2286 double ThetaY=sc_rot_angles[1]*M_PI3.14159265358979323846/180.;
2287 Get("//posXYZ[@volume='StartCntr']/@rot", sc_rot_angles);
2288 //double ThetaX=sc_rot_angles[0]*M_PI/180.;
2289 //double ThetaY=sc_rot_angles[1]*M_PI/180.;
2290 double ThetaZ=sc_rot_angles[2]*M_PI3.14159265358979323846/180.;
2291
2292 // Get overall alignment shifts from CCDB
2293 map<string,double> sc_global_offsets;
2294 if (jcalib->Get("START_COUNTER/global_alignment_parms",sc_global_offsets)==false) {
2295 // translations
2296 dx += sc_global_offsets["SC_ALIGN_X"];
2297 dy += sc_global_offsets["SC_ALIGN_Y"];
2298 z0 += sc_global_offsets["SC_ALIGN_Z"];
2299
2300 // rotations
2301 ThetaX += sc_global_offsets["SC_ALIGN_ROTX"]*M_PI3.14159265358979323846/180.;
2302 ThetaY += sc_global_offsets["SC_ALIGN_ROTY"]*M_PI3.14159265358979323846/180.;
2303 ThetaZ += sc_global_offsets["SC_ALIGN_ROTZ"]*M_PI3.14159265358979323846/180.;
2304 }
2305
2306 double num_paddles;
2307 Get("//mposPhi[@volume='STRC']/@ncopy",num_paddles);
2308 double dSCdphi = M_TWO_PI6.28318530717958647692/num_paddles;
2309
2310 vector<vector<double> > sc_rioz;
2311 GetMultiple("//pgon[@name='STRC']/polyplane/@Rio_Z", sc_rioz);
2312
2313 // Get individual paddle alignment parameters
2314 vector< map<string,double> > sc_paddle_offsets;
2315 bool loaded_paddle_offsets = false;
2316 if (jcalib->Get("START_COUNTER/paddle_alignment_parms",sc_paddle_offsets)==false)
2317 loaded_paddle_offsets = true;
2318
2319 // Create vectors of positions and normal vectors for each paddle
2320 for (unsigned int i=0;i<30;i++){
2321 double phi=ThetaZ+dSCdphi*(double(i)+0.5);
2322 double sinphi=sin(phi);
2323 double cosphi=cos(phi);
2324 double r=0.5*(sc_rioz[0][0]+sc_rioz[0][1]);
2325 DVector3 oldray;
2326 // Rotate by phi and take into account the tilt
2327 double x=r*cosphi;//+dx;
2328 double y=r*sinphi;//+dy;
2329 DVector3 ray(x,y,sc_rioz[0][2]);
2330 ray.RotateX(ThetaX);
2331 ray.RotateY(ThetaY);
2332
2333 // Create stl-vectors to store positions and norm vectors
2334 vector<DVector3>posvec;
2335 vector<DVector3>dirvec;
2336 // Loop over radial/z positions describing start counter geometry from xml
2337 for(unsigned int k = 1; k < sc_rioz.size(); ++k){
2338 oldray=ray;
2339 r=0.5*(sc_rioz[k][0]+sc_rioz[k][1]);
2340 // Point in plane of scintillator
2341 x=r*cosphi;//+dx;
2342 y=r*sinphi;//+dy;
2343 ray.SetXYZ(x,y,sc_rioz[k][2]);
2344 ray.RotateX(ThetaX);
2345 ray.RotateY(ThetaY);
2346 // Apply alignment parameters
2347 if(loaded_paddle_offsets) {
2348 // allow for a maximum extent of the paddle in z
2349 double max_z = sc_paddle_offsets[i]["SC_MAX_Z"];
2350 if(ray.Z() > max_z) {
2351 ray.SetZ(max_z);
2352 }
2353 // allow for a modification of the bend angle of the paddle (18.5 deg from horizontal)
2354 // this should just be a perturbation around this angle, so assume a linear interpolation
2355 double delta_theta = sc_paddle_offsets[i]["SC_CURVE_THETA"]; // in degrees, r of curvature = 120 cm
2356 ray.SetX(ray.X()+delta_theta*1.65); // 1 degree ~ 1.65 cm in x
2357 ray.SetY(ray.Y()-delta_theta*0.55); // 1 degree ~ 0.55 cm in y
2358 }
2359 // Second point in the plane of the scintillator
2360 DVector3 ray2(r,10.,sc_rioz[k][2]);
2361 ray2.RotateZ(phi+0.5*dSCdphi*(1.+1./15.*((i>14)?29-i:i)));
2362 ray2.RotateX(ThetaX);
2363 ray2.RotateY(ThetaY);
2364 // Compute normal vector to plane
2365 DVector3 dir=(ray-oldray).Cross(ray2-oldray);
2366 dir.SetMag(1.);
2367 dirvec.push_back(dir);
2368 posvec.push_back(DVector3(oldray.X()+dx,oldray.Y()+dy,oldray.Z()+z0));
2369 }
2370 posvec.push_back(DVector3(ray.X(),ray.Y(),ray.Z()+z0)); //SAVE THE ENDPOINT OF THE LAST PLANE
2371 pos.push_back(posvec);
2372 norm.push_back(dirvec);
2373
2374 posvec.clear();
2375 dirvec.clear();
2376 }
2377
2378 }
2379 return got_sc;
2380}
2381

libraries/HDGEOMETRY/DGeometry.h

1// $Id$
2//
3// File: DGeometry.h
4// Created: Thu Apr 3 08:43:06 EDT 2008
5// Creator: davidl (on Darwin swire-d95.jlab.org 8.11.1 i386)
6//
7
8#ifndef _DGeometry_
9#define _DGeometry_
10
11#include <pthread.h>
12#include <map>
13
14#include <JANA/jerror.h>
15#include <JANA/JGeometry.h>
16using namespace jana;
17
18#include <DANA/DApplication.h>
19#include "FDC/DFDCGeometry.h"
20#include "FDC/DFDCWire.h"
21#include "FDC/DFDCCathode.h"
22#include "CDC/DCDCWire.h"
23
24#include <particleType.h>
25#include <DVector3.h>
26#include "DMaterial.h"
27#include "DMaterialMap.h"
28using namespace jana;
29
30class DApplication;
31class DMagneticFieldMap;
32class DLorentzDeflections;
33
34
35class DGeometry{
36 public:
37 DGeometry(JGeometry *jgeom, DApplication *dapp, int32_t runnumber);
38 virtual ~DGeometry();
39 virtual const char* className(void){return static_className();}
40 static const char* static_className(void){return "DGeometry";}
41
42 JGeometry* GetJGeometry(void) {return jgeom;}
43 DMagneticFieldMap* GetBfield(void) const;
44 DLorentzDeflections *GetLorentzDeflections(void);
45
46 // These methods just map to the same methods in JGeometry. Ideally, we'd
47 // base DGeometry on JGeometry and so we'd get these automatically.
48 // However, that would require a more complicated generator mechanism
49 // where the geometry objects are made outside of JANA.
50 bool Get(string xpath, string &sval) const {return jgeom->Get(xpath, sval);}
51 bool Get(string xpath, map<string, string> &svals) const {return jgeom->Get(xpath, svals);}
52 template<class T> bool Get(string xpath, T &val) const {return jgeom->Get(xpath, val);}
3
Calling 'JGeometry::Get'
7
Returning from 'JGeometry::Get'
8
Returning without writing to 'val'
53 template<class T> bool Get(string xpath, vector<T> &vals, string delimiter=" ") const {return jgeom->Get(xpath, vals, delimiter);}
54 template<class T> bool Get(string xpath, map<string,T> &vals) const {return jgeom->Get(xpath, vals);}
55
56 // The GNU 3.2.3 compiler has a problem resolving the ambiguity between
57 // Get(string, T&val) and Get(string, vector<T> &vals, string) above.
58 // This does not seem to be a problem with the 4.0 compiler. To get
59 // around this, some non-templated versions are provided (eeech!).
60 bool Get(string xpath, vector<double> &vals, string delimiter=" ") const {return jgeom->Get(xpath, vals, delimiter);}
61 bool Get(string xpath, vector<int> &vals, string delimiter=" ") const {return jgeom->Get(xpath, vals, delimiter);}
62 bool Get(string xpath, vector<float> &vals, string delimiter=" ") const {return jgeom->Get(xpath, vals, delimiter);}
63
64 bool GetMultiple(string xpath,vector<vector<double> >&vals,
65 string delimiter=" ") const
66 {return jgeom->GetMultiple(xpath,vals,delimiter);}
67
68 typedef struct{
69 double du,dphi,dz;
70 }fdc_wire_offset_t;
71 typedef struct{
72 double dPhiX,dPhiY,dPhiZ;
73 }fdc_wire_rotation_t;
74 typedef struct{
75 double du,dphi;
76 }fdc_cathode_offset_t;
77 typedef struct{
78 double dx_u,dy_u,dx_d,dy_d;
79 }cdc_offset_t;
80
81 typedef pair<string, map<string,string> > node_t;
82 typedef vector<node_t> xpathparsed_t;
83
84 void FindNodes(string xpath, vector<xpathparsed_t> &matched_xpaths) const;
85
86 // Methods for accessing material map tables obtained from calibDB
87 jerror_t FindMat(DVector3 &pos, double &rhoZ_overA, double &rhoZ_overA_logI, double &RadLen) const;
88 jerror_t FindMat(DVector3 &pos, double &density, double &A, double &Z, double &RadLen) const;
89 jerror_t FindMatALT1(DVector3 &pos, DVector3 &mom, double &KrhoZ_overA,
90 double &rhoZ_overA,double &LnI,
91 double &X0, double *s_to_boundary=NULL__null) const;
92 jerror_t FindMatKalman(const DVector3 &pos,const DVector3 &mom,
93 double &KrhoZ_overA,
94 double &rhoZ_overA,double &LnI,double &Z,
95 double &chi2c_factor,
96 double &chi2a_factor,
97 double &chi2a_factor2,
98 unsigned int &last_index,
99 double *s_to_boundary=NULL__null) const;
100 jerror_t FindMatKalman(const DVector3 &pos,const DVector3 &mom,
101 double &KrhoZ_overA,
102 double &rhoZ_overA,double &LnI,double &Z,
103 unsigned int &last_index,
104 double *s_to_boundary=NULL__null) const;
105 jerror_t FindMatKalman(const DVector3 &pos,
106 double &KrhoZ_overA,
107 double &rhoZ_overA,double &LnI,
108 double &Z,
109 double &chi2c_factor,
110 double &chi2a_factor,
111 double &chi2a_factor2,
112 unsigned int &last_index) const;
113 jerror_t FindMatKalman(const DVector3 &pos,
114 double &KrhoZ_overA,
115 double &rhoZ_overA,double &LnI,
116 double &Z,unsigned int &last_index) const;
117
118 const DMaterialMap::MaterialNode* FindMatNode(DVector3 &pos) const;
119 const DMaterialMap* FindDMaterialMap(DVector3 &pos) const;
120
121 // Convenience methods
122 const DMaterial* GetDMaterial(string name) const;
123
124 bool GetFDCWires(vector<vector<DFDCWire *> >&fdcwires) const;
125 bool GetFDCCathodes(vector<vector<DFDCCathode *> >&fdccathodes) const;
126 bool GetFDCZ(vector<double> &z_wires) const; ///< z-locations for each of the FDC wire planes in cm
127 bool GetFDCStereo(vector<double> &stereo_angles) const; ///< stereo angles of each of the FDC wire layers
128 bool GetFDCRmin(vector<double> &rmin_packages) const; ///< beam hole size for each FDC package in cm
129 bool GetFDCRmax(double &rmax_active_fdc) const; ///< outer radius of FDC active area in cm
130
131 bool GetCDCWires(vector<vector<DCDCWire *> >&cdcwires) const;
132 bool GetCDCOption(string &cdc_option) const; ///< get the centralDC_option-X string
133 bool GetCDCCenterZ(double &cdc_center_z) const; ///< z-location of center of CDC wires in cm
134 bool GetCDCAxialLength(double &cdc_axial_length) const; ///< length of CDC axial wires in cm
135 bool GetCDCStereo(vector<double> &cdc_stereo) const; ///< stereo angle for each CDC layer in degrees
136 bool GetCDCRmid(vector<double> &cdc_rmid) const; ///< Distance of the center of CDC wire from beamline for each layer in cm
137 bool GetCDCNwires(vector<int> &cdc_nwires) const; ///< Number of wires for each CDC layer
138 bool GetCDCEndplate(double &z,double &dz,double &rmin,double &rmax) const;
139 bool GetCDCAxialWires(unsigned int ring,unsigned int ncopy,
140 double zcenter,double dz,
141 vector<vector<cdc_offset_t> >&cdc_offsets,
142 vector<DCDCWire*> &axialwires,
143 vector<double>&rot_angles,double dx,
144 double dy) const;
145 bool GetCDCStereoWires(unsigned int ring,unsigned int ncopy,
146 double zcenter,
147 double dz,
148 vector<vector<cdc_offset_t> >&cdc_offsets,
149 vector<DCDCWire*> &stereowires,
150 vector<double>&rot_angles,
151 double dx,double dy) const;
152
153 bool GetBCALRmin(float &bcal_rmin) const; ///< minimum distance of BCAL module from beam line
154 bool GetBCALfADCRadii(vector<float> &fADC_radii) const; ///< fADC radii including the outer radius of the last layer
155 bool GetBCALNmodules(unsigned int &bcal_nmodules) const; ///< Number of BCAL modules
156 bool GetBCALCenterZ(float &bcal_center_z) const; ///< z-location of center of BCAL module in cm
157 bool GetBCALLength(float &bcal_length) const; ///< length of BCAL module in cm
158 bool GetBCALDepth(float &bcal_depth) const; ///< depth (or height) of BCAL module in cm
159 bool GetBCALPhiShift(float &bcal_phi_shift) const; ///< phi angle in degrees that first BCAL module is shifted from being centered at ph=0.0
160
161 bool GetCCALZ(double &z_ccal) const; /// z-location of front face of CCAL in cm
162
163 bool GetFCALZ(double &z_fcal) const; ///< z-location of front face of FCAL in cm
164 bool GetDIRCZ(double &z_dirc) const; ///< z-location of DIRC in cm
165 bool GetTOFZ(vector<double> &z_tof) const; ///< z-location of front face of each of TOF in cm
166 bool GetTOFPaddlePerpPositions(vector<double> &y_tof, vector<double> &y_widths) const;
167 bool GetTOFPaddleParameters(map<string,double> &paddle_params) const;
168 bool GetTargetZ(double &z_target) const; ///< z-location of center of target
169 bool GetTargetLength(double &target_length) const; ///< z-location of center of target
170
171 bool GetTRDZ(vector<double> &z_trd) const; ///< z-locations for each of the TRD/GEM planes in cm
172
173 bool GetFCALPosition(double &x,double &y,double &z) const;
174 bool GetCCALPosition(double &x,double &y,double &z) const;
175
176 bool GetFCALInsertRowSize(int &insert_row_size) const;
177 bool GetFCALBlockSize(vector<double> &block) const;
178 bool GetFCALInsertBlockSize(vector<double> &block) const;
179
180 bool GetStartCounterGeom(vector<vector<DVector3> >&pos,
181 vector<vector<DVector3> >&norm) const; // < vectors containing positions and norm 3-vectors for start counter
182 // There are 30 sets of positions (pos) of points along the
183 // start counter, one set for each paddle, and a corresponding
184 // set of norms at various points along the start counter.
185 // For example, to access the most upstream point of paddle 1
186 // use pos[0][0]. The end of the barrel section before the
187 // nose region is at pos[0][1]. The tip of the nose region
188 // for this paddle is at pos[0][pos[0].size()-1]. The bend
189 // region is modeled by many closely-spaced points starting
190 // after pos[0][1].
191
192 vector<DMaterialMap*> GetMaterialMapVector(void) const;
193
194 protected:
195 DGeometry(){}
196 void ReadMaterialMaps(void) const;
197 void GetMaterials(void) const;
198 bool GetCompositeMaterial(const string &name, double &density, double &radlen) const;
199
200 private:
201 JGeometry *jgeom;
202 DApplication *dapp;
203 mutable DMagneticFieldMap *bfield;
204 int32_t runnumber;
205 mutable vector<DMaterial*> materials; /// Older implementation to keep track of material specs without ranges
206 mutable vector<DMaterialMap*> materialmaps; /// Material maps generated automatically(indirectly) from XML with ranges and specs
207 mutable bool materialmaps_read;
208 mutable bool materials_read;
209
210 mutable pthread_mutex_t bfield_mutex;
211 mutable pthread_mutex_t materialmap_mutex;
212 mutable pthread_mutex_t materials_mutex;
213
214
215};
216
217#endif // _DGeometry_
218

/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JGeometry.h

1// $Id$
2//
3// File: JGeometry.h
4// Created: Fri Jul 6 16:24:24 EDT 2007
5// Creator: davidl (on Darwin fwing-dhcp61.jlab.org 8.10.1 i386)
6//
7
8#ifndef _JGeometry_
9#define _JGeometry_
10
11#include "jerror.h"
12
13#include <map>
14#include <string>
15#include <sstream>
16#include <vector>
17using std::map;
18using std::string;
19using std::stringstream;
20using std::vector;
21
22// Place everything in JANA namespace
23namespace jana{
24
25/// JGeometry is a virtual base class used to define the interface by
26/// which geometry information can be obtained in JANA.
27/// Implementing this base class allows the JANA end user to be
28/// agnostic as to the details of how the geometry info is stored.
29/// The geometry can be stored in a database or any number of file
30/// formats. The files can be stored locally, or on the network
31/// somewhere.
32///
33/// The primary advantage here is that it allows one to work with
34/// local files, but then easily switch to a remote source method
35/// when appropriate without requiring modifications to the end
36/// user code.
37///
38/// On the user side they will call one of the Get(...) methods which all get
39/// translated into a call of one of the two vitural methods:
40///
41/// virtual bool Get(string namepath, string &sval, map<string, string> &where)=0;
42/// virtual bool Get(string namepath, map<string, string> &svals, map<string, string> &where)=0;
43///
44/// These two virtual methods along with one to get a list of the available
45/// namepaths are the only things that need to be implemented
46/// in a concrete subclass of JGeometry.
47///
48/// A geometry element is specified by its <i>namepath</i> and an optional
49/// set of qualifiers (the <i>where</i> argument). The <i>namepath</i>
50/// is a hierarchal list of elements separated by forward slashes(/)
51/// analogous to a path on a unix filesystem. This path is always assumed
52/// to be relative to the <i>url</i> specified in the constructor. So,
53/// for instance, suppose one kept the geometry in a set XML files on the
54/// local filesystem and wished to access information from the file
55///
56/// <tt>/home/joe/calib/geom_Oct10_2017.xml</tt>
57///
58/// One would specify the <i>url</i> as:
59///
60/// file:///home/joe/calib/geom_Oct10_2017.xml
61///
62/// and then the namepath could be specified as the string:
63///
64/// "TOF/bar/X_Y_Z"
65///
66/// which would indicate the attribute <i>"X_Y_Z"</i> of the
67/// subtag <i>"bar"</i> of the tag <i>"TOF"</i> in the file
68/// <i>"/home/joe/calib/geom_Oct10_2017.xml"</i>
69
70class JGeometry{
71 public:
72 JGeometry(string url, int run, string context="default"){
73 this->url = url;
74 this->run_requested = run;
75 this->context = context;
76 }
77 virtual ~JGeometry(){}
78 virtual const char* className(void){return static_className();}
79 static const char* static_className(void){return "JGeometry";}
80
81 typedef enum{
82 // Used to specify which (if any) attributes should be included in
83 // the values obtained through GetXPaths().
84 attr_level_none = 0, // Don't include any attributes. Only node names.
85 attr_level_last = 1, // Include the attributes for the last node only.
86 attr_level_all = 2 // Include attributes for all nodes.
87 }ATTR_LEVEL_t;
88
89 void SetVerbose(int newval){ verbose = newval; }
90
91 // Virtual methods called through base class
92 virtual bool Get(string xpath, string &sval)=0;
93 virtual bool Get(string xpath, map<string, string> &svals)=0;
94 virtual bool GetMultiple(string xpath, vector<string> &vsval)=0;
95 virtual bool GetMultiple(string xpath, vector<map<string, string> >&vsvals)=0;
96 virtual void GetXPaths(vector<string> &xpaths, ATTR_LEVEL_t level=attr_level_last, const string &filter="")=0;
97 virtual string GetChecksum(void) const {return string("not supported");}
98
99 // Templated methods that can return more useful forms
100 template<class T> bool Get(string xpath, T &val);
101 template<class T> bool Get(string xpath, vector<T> &vals, string delimiter=" ");
102 template<class T> bool Get(string xpath, map<string,T> &vals);
103 template<class T> bool GetMultiple(string xpath, vector<T> &vval);
104 template<class T> bool GetMultiple(string xpath, vector<vector<T> > &vvals, string delimiter=" ");
105 template<class T> bool GetMultiple(string xpath, vector<map<string,T> > &vvals);
106
107 const int& GetRunRequested(void) const {return run_requested;}
108 const int& GetRunFound(void) const {return run_found;}
109 const int& GetRunMin(void) const {return run_min;}
110 const int& GetRunMax(void) const {return run_max;}
111 const string& GetContext(void) const {return context;}
112 const string& GetURL(void) const {return url;}
113
114 protected:
115 int run_min;
116 int run_max;
117 int run_found;
118
119 int verbose=1;
120
121 private:
122 JGeometry(){} // Don't allow trivial constructor
123
124 int run_requested;
125 string context;
126 string url;
127 map<string,string> anywhere; // an empty map means no constraints
128
129};
130
131
132//-------------
133// Get (single version)
134//-------------
135template<class T>
136bool JGeometry::Get(string xpath, T &val)
137{
138 /// Templated method used to get a single geometry element.
139 ///
140 /// This method will get the specified geometry element in the form of
141 /// a string using the virtual (non-templated) Get(...) method. It will
142 /// then convert the string into the data type on which <i>val</i> is
143 /// based. It does this using the stringstream
144 /// class so T is restricted to the types stringstream understands (int, float,
145 /// double, string, ...).
146 ///
147 /// If no element of the specified name is found, a value
148 /// of boolean "false" is returned. A value of "true" is
149 /// returned upon success.
150
151 // Get values in the form of a string
152 string sval;
153 bool res = Get(xpath, sval);
154 if(!res)return res;
4
Assuming 'res' is false
5
Taking true branch
6
Returning without writing to 'val'
155
156 // Convert the string to type "T" and copy it into val.
157 // Use stringstream to convert from a string to type "T"
158 stringstream ss(sval);
159 ss >> val;
160
161 return res;
162}
163
164//-------------
165// Get (vector version)
166//-------------
167template<class T>
168bool JGeometry::Get(string xpath, vector<T> &vals, string delimiter)
169{
170 /// Templated method used to get a set of values from a geometry attribute.
171 ///
172 /// This method can be used to get a list of values (possibly only one)
173 /// from a single geometry attribute specified by xpath. The attribute
174 /// is obtained as a string using the non-templated Get(...) method
175 /// and the string broken into tokens separated by the delimiter
176 /// (which defaults to a single white space). Each
177 /// token is then converted into type T using the stringstream class
178 /// so T is restricted to the types stringstream understands (int, float,
179 /// double, string, ...).
180 ///
181 /// If no element of the specified name is found, a value
182 /// of boolean "false" is returned. A value of "true" is
183 /// returned upon success.
184
185 // Get values in the form of strings
186 vals.clear();
187 string svals;
188 bool res = Get(xpath, svals);
189 if(!res)return res;
190
191 string::size_type pos_start = svals.find_first_not_of(delimiter,0);
192 while(pos_start != string::npos){
193 string::size_type pos_end = svals.find_first_of(delimiter, pos_start);
194 if(pos_end==string::npos)pos_end=svals.size();
195
196 T v;
197 string val = svals.substr(pos_start, pos_end-pos_start);
198 stringstream ss(val);
199 ss >> v;
200 vals.push_back(v);
201
202 pos_start = svals.find_first_not_of(delimiter, pos_end);
203 }
204
205 return res;
206}
207
208//-------------
209// Get (map version)
210//-------------
211template<class T>
212bool JGeometry::Get(string xpath, map<string,T> &vals)
213{
214 /// Templated method used to get a set of geometry attributes.
215 ///
216 /// This method can be used to get a list of all attributes for
217 /// a given xpath. The attributes are copied into the <i>vals</i>
218 /// map with the attribute name as the key and the attribute
219 /// value as the value. This relies on the non-templated, virtual
220 /// Get(string, map<string,string>&) method to first get the values
221 /// in the form of strings. It converts them using the stringstream
222 /// class so T is restricted to the types it understands (int, float,
223 /// double, string, ...).
224 ///
225 /// If no element of the specified name is found, a value
226 /// of boolean "false" is returned. A value of "true" is
227 /// returned upon success.
228
229 // Get values in the form of strings
230 map<string, string> svals;
231 bool res = Get(xpath, svals);
232
233 // Loop over values, converting the strings to type "T" and
234 // copying them into the vals map.
235 vals.clear();
236 map<string,string>::const_iterator iter;
237 for(iter=svals.begin(); iter!=svals.end(); ++iter){
238 // Use stringstream to convert from a string to type "T"
239 T v;
240 stringstream ss(iter->second);
241 ss >> v;
242 vals[iter->first] = v;
243 }
244
245 return res;
246}
247
248
249//-------------
250// GetMultiple (single version)
251//-------------
252template<class T>
253bool JGeometry::GetMultiple(string xpath, vector<T> &vval)
254{
255 /// Templated method used to get multiple entries satisfying a single xpath.
256 ///
257 /// This method will get the specified geometry element in the form of
258 /// a string using the virtual (non-templated) Get(...) method. It will
259 /// then convert the string into the data type on which <i>val</i> is
260 /// based. It does this using the stringstream
261 /// class so T is restricted to the types stringstream understands (int, float,
262 /// double, string, ...).
263 ///
264 /// This differs from the similar Get() method in that the geometry tree
265 /// will be searched for all nodes satisfying the given xpath and all
266 /// all values will be copied into the container provided. In Get(), only
267 /// the first node encountered that satisfies the xpath will be copied.
268 ///
269 /// If no element of the specified name is found, a value
270 /// of boolean "false" is returned. A value of "true" is
271 /// returned upon success.
272
273 // Get values in the form of a string
274 vector<string> vsval;
275 bool res = GetMultiple(xpath, vsval);
276 if(!res)return res;
277
278 // Convert the string to type "T" and copy it into val.
279 // Use stringstream to convert from a string to type "T"
280 for(unsigned int i=0; i<vsval.size(); i++){
281 stringstream ss(vsval[i]);
282 T val;
283 ss >> val;
284 vval.push_back(val);
285 }
286
287 return res;
288}
289
290//-------------
291// GetMultiple (vector version)
292//-------------
293template<class T>
294bool JGeometry::GetMultiple(string xpath, vector<vector<T> > &vvals, string delimiter)
295{
296 /// Templated method used to get a set of values from a geometry attribute.
297 ///
298 /// This method can be used to get a list of values (possibly only one)
299 /// from a single geometry attribute specified by xpath. The attribute
300 /// is obtained as a string using the non-templated Get(...) method
301 /// and the string broken into tokens separated by the delimiter
302 /// (which defaults to a single white space). Each
303 /// token is then converted into type T using the stringstream class
304 /// so T is restricted to the types stringstream understands (int, float,
305 /// double, string, ...).
306 ///
307 /// If no element of the specified name is found, a value
308 /// of boolean "false" is returned. A value of "true" is
309 /// returned upon success.
310
311 // Get values in the form of strings
312 vvals.clear();
313 vector<string> vsvals;
314 bool res = GetMultiple(xpath, vsvals);
315 if(!res)return res;
316
317 for(unsigned int i=0; i<vsvals.size(); i++){
318 string &svals = vsvals[i];
319
320 string::size_type pos_start = svals.find_first_not_of(delimiter,0);
321 vector<T> vals;
322 while(pos_start != string::npos){
323 string::size_type pos_end = svals.find_first_of(delimiter, pos_start);
324 if(pos_end==string::npos)pos_end=svals.size();
325
326 T v;
327 string val = svals.substr(pos_start, pos_end-pos_start);
328 stringstream ss(val);
329 ss >> v;
330 vals.push_back(v);
331
332 pos_start = svals.find_first_not_of(delimiter, pos_end);
333 }
334
335 vvals.push_back(vals);
336 }
337
338 return res;
339}
340
341//-------------
342// GetMultiple (map version)
343//-------------
344template<class T>
345bool JGeometry::GetMultiple(string xpath, vector<map<string,T> > &vvals)
346{
347 /// Templated method used to get a set of geometry attributes.
348 ///
349 /// This method can be used to get a list of all attributes for
350 /// a given xpath. The attributes are copied into the <i>vals</i>
351 /// map with the attribute name as the key and the attribute
352 /// value as the value. This relies on the non-templated, virtual
353 /// Get(string, map<string,string>&) method to first get the values
354 /// in the form of strings. It converts them using the stringstream
355 /// class so T is restricted to the types it understands (int, float,
356 /// double, string, ...).
357 ///
358 /// If no element of the specified name is found, a value
359 /// of boolean "false" is returned. A value of "true" is
360 /// returned upon success.
361
362 // Get values in the form of strings
363 vector<map<string, string> > vsvals;
364 bool res = GetMultiple(xpath, vsvals);
365
366 // Loop over values, converting the strings to type "T" and
367 // copying them into the vals map.
368 vvals.clear();
369
370 for(unsigned int i=0; i<vsvals.size(); i++){
371 map<string,string> &svals = vsvals[i];
372
373 map<string,T> vals;
374 map<string,string>::const_iterator iter;
375 for(iter=svals.begin(); iter!=svals.end(); ++iter){
376 // Use stringstream to convert from a string to type "T"
377 T v;
378 stringstream ss(iter->second);
379 ss >> v;
380 vals[iter->first] = v;
381 }
382
383 vvals.push_back(vals);
384 }
385
386 return res;
387}
388
389} // Close JANA namespace
390
391#endif // _JGeometry_