Bug Summary

File:/volatile/halld/gluex/nightly/2024-03-18/Linux_CentOS7.7-x86_64-gcc4.8.5/halld_recon/src/libraries/HDGEOMETRY/DGeometry.cc
Location:line 2356, column 4
Description:Value stored to 'num_bars' is never read

Annotated Source Code

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
1788//---------------------------------
1789// GetCTOFZ
1790//---------------------------------
1791bool DGeometry::GetCTOFZ(double &z) const {
1792 z=1000; // cm; initialize to a large value
1793 vector<double> CppScintPos;
1794 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1795 bool good = Get("//section/composition/posXYZ[@volume='CppScint']/@X_Y_Z", CppScintPos);
1796 jgeom->SetVerbose(1); // reenable error messages
1797 if (!good){
1798 //_DBG_<<"Unable to retrieve CPP scintillator position."<<endl;
1799 return false;
1800 }
1801 z=CppScintPos[2];
1802 return true;
1803}
1804
1805//---------------------------------
1806// GetCTOFPositions
1807//---------------------------------
1808bool DGeometry::GetCTOFPositions(vector<DVector3>&posvec) const{
1809 vector<double>origin;
1810 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1811 bool good = Get("//section/composition/posXYZ[@volume='CppScint']/@X_Y_Z",origin);
1812 jgeom->SetVerbose(1); // reenable error messages
1813 if (!good) return false;
1814 DVector3 pos(origin[0],origin[1],origin[2]);
1815 for (unsigned int paddle=1;paddle<5;paddle++){
1816 vector<double>local_pos;
1817 Get(Form("//posXYZ[@volume='CPPPaddle']/@X_Y_Z/column[@value='%d']",paddle),local_pos);
1818 DVector3 dpos(local_pos[0],local_pos[1],local_pos[2]);
1819 posvec.push_back(pos+dpos);
1820 }
1821
1822 return true;
1823}
1824
1825//---------------------------------
1826// GetFMWPCZ
1827//---------------------------------
1828bool DGeometry::GetFMWPCZ_vec(vector<double>&zvec_fmwpc) const
1829{
1830 vector<double> ForwardMWPCpos;
1831 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1832 bool good = Get("//section/composition/posXYZ[@volume='ForwardMWPC']/@X_Y_Z", ForwardMWPCpos);
1833 jgeom->SetVerbose(1); // reenable error messages
1834 if (!good){
1835 //_DBG_<<"Unable to retrieve ForwardMWPC position."<<endl;
1836 return false;
1837 }
1838
1839 vector<double>CPPChamberPos;
1840 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='1']", CPPChamberPos);
1841 zvec_fmwpc.push_back(ForwardMWPCpos[2]+CPPChamberPos[2]);
1842 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='2']", CPPChamberPos);
1843 zvec_fmwpc.push_back(ForwardMWPCpos[2]+CPPChamberPos[2]);
1844 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='3']", CPPChamberPos);
1845 zvec_fmwpc.push_back(ForwardMWPCpos[2]+CPPChamberPos[2]);
1846 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='4']", CPPChamberPos);
1847 zvec_fmwpc.push_back(ForwardMWPCpos[2]+CPPChamberPos[2]);
1848 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='5']", CPPChamberPos);
1849 zvec_fmwpc.push_back(ForwardMWPCpos[2]+CPPChamberPos[2]);
1850 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='6']", CPPChamberPos);
1851 zvec_fmwpc.push_back(ForwardMWPCpos[2]+CPPChamberPos[2]);
1852
1853 return true;
1854}
1855
1856//---------------------------------
1857// GetFMWPCXY
1858//---------------------------------
1859bool DGeometry::GetFMWPCXY_vec(vector<double>&xvec_fmwpc, vector<double>&yvec_fmwpc) const
1860{
1861 vector<double> ForwardMWPCpos;
1862 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1863 bool good = Get("//section/composition/posXYZ[@volume='ForwardMWPC']/@X_Y_Z", ForwardMWPCpos);
1864 jgeom->SetVerbose(1); // reenable error messages
1865 if (!good){
1866 //_DBG_<<"Unable to retrieve ForwardMWPC position."<<endl;
1867 return false;
1868 }
1869
1870 // Get offsets tweaking nominal geometry from calibration database
1871 // JCalibration * jcalib = dapp->GetJCalibration(runnumber);
1872
1873 vector<double>CPPChamberPos;
1874 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='1']", CPPChamberPos);
1875 xvec_fmwpc.push_back(ForwardMWPCpos[0]+CPPChamberPos[0]);
1876 yvec_fmwpc.push_back(ForwardMWPCpos[1]+CPPChamberPos[1]);
1877 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='2']", CPPChamberPos);
1878 xvec_fmwpc.push_back(ForwardMWPCpos[0]+CPPChamberPos[0]);
1879 yvec_fmwpc.push_back(ForwardMWPCpos[1]+CPPChamberPos[1]);
1880 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='3']", CPPChamberPos);
1881 xvec_fmwpc.push_back(ForwardMWPCpos[0]+CPPChamberPos[0]);
1882 yvec_fmwpc.push_back(ForwardMWPCpos[1]+CPPChamberPos[1]);
1883 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='4']", CPPChamberPos);
1884 xvec_fmwpc.push_back(ForwardMWPCpos[0]+CPPChamberPos[0]);
1885 yvec_fmwpc.push_back(ForwardMWPCpos[1]+CPPChamberPos[1]);
1886 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='5']", CPPChamberPos);
1887 xvec_fmwpc.push_back(ForwardMWPCpos[0]+CPPChamberPos[0]);
1888 yvec_fmwpc.push_back(ForwardMWPCpos[1]+CPPChamberPos[1]);
1889 Get("//posXYZ[@volume='CPPChamber']/@X_Y_Z/layer[@value='6']", CPPChamberPos);
1890 xvec_fmwpc.push_back(ForwardMWPCpos[0]+CPPChamberPos[0]);
1891 yvec_fmwpc.push_back(ForwardMWPCpos[1]+CPPChamberPos[1]);
1892
1893 // Currently, not all chambers have a 'rot' field in hdds
1894 // vector<double>CPPChamberRot;
1895 // Get("//posXYZ[@volume='CPPChamber']/@rot/layer[@value='1']", CPPChamberRot);
1896 // rot_fmwpc.push_back(CPPChamberRot[2]);
1897 // Get("//posXYZ[@volume='CPPChamber']/@rot/layer[@value='2']", CPPChamberRot);
1898 // rot_fmwpc.push_back(CPPChamberRot[2]);
1899 // Get("//posXYZ[@volume='CPPChamber']/@rot/layer[@value='3']", CPPChamberRot);
1900 // rot_fmwpc.push_back(CPPChamberRot[2]);
1901 // Get("//posXYZ[@volume='CPPChamber']/@rot/layer[@value='4']", CPPChamberRot);
1902 // rot_fmwpc.push_back(CPPChamberRot[2]);
1903 // Get("//posXYZ[@volume='CPPChamber']/@rot/layer[@value='5']", CPPChamberRot);
1904 // rot_fmwpc.push_back(CPPChamberRot[2]);
1905 // Get("//posXYZ[@volume='CPPChamber']/@rot/layer[@value='6']", CPPChamberRot);
1906 // rot_fmwpc.push_back(CPPChamberRot[2]);
1907
1908 return true;
1909}
1910
1911//---------------------------------
1912// GetFMWPCSize -- use the dimensions of the frame
1913//---------------------------------
1914bool DGeometry::GetFMWPCSize(double &xy_fmwpc) const
1915{
1916 vector<double> ForwardMWPCdimensions;
1917 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
1918 bool good = Get("//section[@name='ForwardMWPC']/box[@name='CPPF']/@X_Y_Z", ForwardMWPCdimensions);
1919 jgeom->SetVerbose(1); // reenable error messages
1920 if (!good){
1921 xy_fmwpc=0.0;
1922 return false;
1923 }
1924 xy_fmwpc=0.5*ForwardMWPCdimensions[0];
1925
1926 return true;
1927}
1928
1929//---------------------------------
1930// GetFMWPCWireSpacing -- space between wires in cm
1931//---------------------------------
1932bool DGeometry::GetFMWPCWireSpacing(double &fmwpc_wire_spacing) const
1933{
1934 fmwpc_wire_spacing = 1.016;
1935
1936 return true;
1937}
1938
1939//---------------------------------
1940// GetFMWPCWireSpacing -- space between wires in cm
1941//---------------------------------
1942bool DGeometry::GetFMWPCWireOrientation(vector<fmwpc_wire_orientation_t> &fmwpc_wire_orientation) const
1943{
1944 fmwpc_wire_orientation.clear();
1945 fmwpc_wire_orientation.push_back( kFMWPC_WIRE_ORIENTATION_VERTICAL );
1946 fmwpc_wire_orientation.push_back( kFMWPC_WIRE_ORIENTATION_HORIZONTAL );
1947 fmwpc_wire_orientation.push_back( kFMWPC_WIRE_ORIENTATION_VERTICAL );
1948 fmwpc_wire_orientation.push_back( kFMWPC_WIRE_ORIENTATION_HORIZONTAL );
1949 fmwpc_wire_orientation.push_back( kFMWPC_WIRE_ORIENTATION_VERTICAL );
1950 fmwpc_wire_orientation.push_back( kFMWPC_WIRE_ORIENTATION_HORIZONTAL );
1951
1952 return true;
1953}
1954
1955//---------------------------------
1956// GetFCALZ
1957//---------------------------------
1958bool DGeometry::GetFCALZ(double &z_fcal) const
1959{
1960 vector<double> ForwardEMcalpos;
1961 bool good = Get("//section/composition/posXYZ[@volume='ForwardEMcal']/@X_Y_Z", ForwardEMcalpos);
1962
1963 if(!good){
1964 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1964<<" "
<<"Unable to retrieve ForwardEMcal position."<<endl;
1965 z_fcal=0.0;
1966 return false;
1967 }else{
1968 z_fcal = ForwardEMcalpos[2];
1969 return true;
1970 }
1971}
1972
1973
1974//---------------------------------
1975// GetFCALPosition
1976//---------------------------------
1977bool DGeometry::GetFCALPosition(double &x,double &y,double &z) const
1978{
1979 vector<double> ForwardEMcalpos;
1980 bool good = Get("//section/composition/posXYZ[@volume='ForwardEMcal']/@X_Y_Z", ForwardEMcalpos);
1981
1982 if(!good){
1983 _DBG_std::cerr<<"libraries/HDGEOMETRY/DGeometry.cc"<<":"
<<1983<<" "
<<"Unable to retrieve ForwardEMcal position."<<endl;
1984 x=0.,y=0.,z=0.;
1985 return false;
1986 }else{
1987 x=ForwardEMcalpos[0],y=ForwardEMcalpos[1],z=ForwardEMcalpos[2];
1988 //_DBG_ << "FCAL position: (x,y,z)=(" << x <<"," << y << "," << z << ")"<<endl;
1989 return true;
1990 }
1991}
1992
1993//---------------------------------
1994// GetCCALPosition
1995//---------------------------------
1996bool DGeometry::GetCCALPosition(double &x,double &y,double &z) const
1997{
1998 vector<double> ComptonEMcalpos;
1999 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2000 bool good = Get("//section/composition/posXYZ[@volume='ComptonEMcal']/@X_Y_Z", ComptonEMcalpos);
2001 jgeom->SetVerbose(1); // reenable error messages
2002
2003 if(!good){
2004 //_DBG_<<"Unable to retrieve ComptonEMcal position."<<endl;
2005 x=0.,y=0.,z=0.;
2006 return false;
2007 }else{
2008 x=ComptonEMcalpos[0],y=ComptonEMcalpos[1],z=ComptonEMcalpos[2];
2009 //_DBG_ << "CCAL position: (x,y,z)=(" << ComptonEMcalpos[0] <<","
2010 // << ComptonEMcalpos[1]<<","<<ComptonEMcalpos[2]<< ")" << endl;
2011 return true;
2012 }
2013}
2014
2015//---------------------------------
2016// GetFCALInsertRowSize
2017//---------------------------------
2018bool DGeometry::GetFCALInsertRowSize(int &insert_row_size) const
2019{
2020 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2021 bool good = Get("//composition[@name='LeadTungstateFullRow']/mposX[@volume='LTBLwrapped']/@ncopy",insert_row_size);
2022 jgeom->SetVerbose(1); // reenable error messages
2023
2024 if(!good){
2025 // NEED TO RETHINK ERROR REPORTING FOR OPTIONAL DETECTOR ELEMENTS
2026 //_DBG_<<"Unable to retrieve ComptonEMcal position."<<endl;
2027 insert_row_size = 0;
2028 return false;
2029 }else{
2030 return true;
2031 }
2032}
2033
2034//---------------------------------
2035// GetFCALBlockSize
2036//---------------------------------
2037bool DGeometry::GetFCALBlockSize(vector<double> &block) const
2038{
2039 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2040 bool good = Get("//box[@name='LGBL']/@X_Y_Z",block);
2041 jgeom->SetVerbose(1); // reenable error messages
2042
2043 if(!good){
2044 // NEED TO RETHINK ERROR REPORTING FOR OPTIONAL DETECTOR ELEMENTS
2045 //_DBG_<<"Unable to retrieve ComptonEMcal position."<<endl;
2046 return false;
2047 }else{
2048 return true;
2049 }
2050}
2051
2052//---------------------------------
2053// GetFCALInsertBlockSize
2054//---------------------------------
2055bool DGeometry::GetFCALInsertBlockSize(vector<double> &block) const
2056{
2057 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2058 bool good = Get("//box[@name='LTB1']/@X_Y_Z",block);
2059 jgeom->SetVerbose(1); // reenable error messages
2060
2061 if(!good){
2062 // NEED TO RETHINK ERROR REPORTING FOR OPTIONAL DETECTOR ELEMENTS
2063 //_DBG_<<"Unable to retrieve ComptonEMcal position."<<endl;
2064 return false;
2065 }else{
2066 return true;
2067 }
2068}
2069
2070//---------------------------------
2071// GetDIRCZ
2072//---------------------------------
2073bool DGeometry::GetDIRCZ(double &z_dirc) const
2074{
2075 vector<double> dirc_face;
2076 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2077 bool good = Get("//section/composition/posXYZ[@volume='DIRC']/@X_Y_Z",dirc_face);
2078 jgeom->SetVerbose(1); // reenable error messages
2079
2080 if(!good){
2081 //_DBG_<<"Unable to retrieve DIRC position."<<endl;
2082 z_dirc=0.0;
2083 return false;
2084 }
2085 else{
2086 vector<double>dirc_plane;
2087 vector<double>dirc_shift;
2088 vector<double>bar_plane;
2089 Get("//composition[@name='DRCC']/posXYZ[@volume='DCML10']/@X_Y_Z/plane[@value='1']", dirc_plane);
2090 Get("//composition[@name='DIRC']/posXYZ[@volume='DRCC']/@X_Y_Z", dirc_shift);
2091 z_dirc=dirc_face[2]+dirc_plane[2]+dirc_shift[2] + 0.8625; // last shift is the average center of quartz bar (585.862)
2092
2093 //jout << "DIRC z position = " << z_dirc << " cm." << endl;
2094 return true;
2095 }
2096}
2097
2098//---------------------------------
2099// GetTRDZ
2100//---------------------------------
2101bool DGeometry::GetTRDZ(vector<double> &z_trd) const
2102{
2103 vector<double> trd_origin;
2104 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2105 bool good = Get("//section/composition/posXYZ[@volume='TRDGEM']/@X_Y_Z",trd_origin);
2106 jgeom->SetVerbose(1); // reenable error messages
2107
2108 if(!good){
2109 //_DBG_<<"Unable to retrieve TRD position."<<endl;
2110 return false;
2111 }
2112 else{
2113 vector<double>trd_G10;
2114 Get("//composition[@name='TRDGEM']/posXYZ[@volume='TGPK']/@X_Y_Z",trd_G10);
2115
2116 jout << "TRD z positions = ";
2117 for(int i=0; i<5; i++) {
2118 vector<double>trd_plane;
2119 Get(Form("//composition[@name='TGPK']/posXYZ[@volume='TRDG']/@X_Y_Z/plane[@value='%d']",i),trd_plane);
2120 double z_trd_plane=trd_origin[2]+trd_G10[2]+trd_plane[2];
2121 jout << z_trd_plane << ", ";
2122 z_trd.push_back(z_trd_plane);
2123 }
2124 jout << "cm" << endl;
2125 }
2126
2127 return true;
2128}
2129//---------------------------------
2130// GetTOFZ
2131//---------------------------------
2132bool DGeometry::GetTOFZ(double &CenterVPlane,double &CenterHPlane,
2133 double &CenterMPlane) const{
2134 // Store the z position for both planes
2135 vector<double>tof_face;
2136 if (!Get("//section/composition/posXYZ[@volume='ForwardTOF']/@X_Y_Z",tof_face)){
2137 return false;
2138 }
2139 vector<double>tof_plane0;
2140 Get("//composition[@name='ForwardTOF']/posXYZ[@volume='forwardTOF']/@X_Y_Z/plane[@value='0']", tof_plane0);
2141 vector<double>tof_plane1;
2142 Get("//composition[@name='ForwardTOF']/posXYZ[@volume='forwardTOF']/@X_Y_Z/plane[@value='1']", tof_plane1);
2143 CenterVPlane=tof_face[2]+tof_plane1[2];
2144 CenterHPlane=tof_face[2]+tof_plane0[2];
2145 // also save position midway between the two planes
2146 CenterMPlane=0.5*(CenterHPlane+CenterVPlane);
2147
2148 return true;
2149}
2150
2151//---------------------------------
2152// GetTOFZ
2153//---------------------------------
2154bool DGeometry::GetTOFZ(vector<double> &z_tof) const
2155{
2156 vector<double> ForwardTOF;
2157 vector<double> forwardTOF[2];
2158 vector<double> FTOC;
2159
2160 if(!Get("//section/composition/posXYZ[@volume='ForwardTOF']/@X_Y_Z", ForwardTOF)) return false;
2161 if(!Get("//composition[@name='ForwardTOF']/posXYZ[@volume='forwardTOF']/@X_Y_Z/plane[@value='0']", forwardTOF[0])) return false;
2162 if(!Get("//composition[@name='ForwardTOF']/posXYZ[@volume='forwardTOF']/@X_Y_Z/plane[@value='1']", forwardTOF[1])) return false;
2163 if(!Get("//box[@name='FTOC' and sensitive='true']/@X_Y_Z", FTOC)) return false;
2164
2165 z_tof.push_back(ForwardTOF[2] + forwardTOF[0][2] - FTOC[2]/2.0);
2166 z_tof.push_back(ForwardTOF[2] + forwardTOF[1][2] - FTOC[2]/2.0);
2167
2168 //cerr << "DGeometry::GetTOFZ() = " << z_tof[0] << " " << z_tof[1] << endl;
2169
2170 return true;
2171}
2172
2173//---------------------------------
2174// GetTOFPaddleParameters
2175//---------------------------------
2176bool DGeometry::GetTOFPaddleParameters(map<string,double> &paddle_params) const
2177{
2178 vector<double> xyz_bar;
2179
2180 // load the number of bars in each area
2181 int num_bars1 = 0;
2182 if(!Get("//composition[@name='forwardTOF_bottom1']/mposY[@volume='FTOC']/@ncopy",num_bars1)) return false;
2183 int num_narrow_bars1 = 0;
2184 if(!Get("//composition[@name='forwardTOF_bottom2']/mposY[@volume='FTOX']/@ncopy",num_narrow_bars1)) return false;
2185 int num_single_end_bars1 = 0;
2186 if(!Get("//composition[@name='forwardTOF_north']/mposY[@volume='FTOH']/@ncopy",num_single_end_bars1)) return false;
2187
2188 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2189 int num_narrower_bars1 = 0; // optional - added during upgrade
2190 Get("//composition[@name='forwardTOF_bottom3']/mposY[@volume='FTOL']/@ncopy",num_narrower_bars1);
2191 int num_narrower_bars2 = 0; // optional - added during upgrade
2192 Get("//composition[@name='forwardTOF_top3']/mposY[@volume='FTOL']/@ncopy",num_narrower_bars2);
2193 jgeom->SetVerbose(1); // reenable error messages
2194
2195 int num_narrow_bars2 = 0;
2196 if(!Get("//composition[@name='forwardTOF_top2']/mposY[@volume='FTOX']/@ncopy",num_narrow_bars2)) return false;
2197 int num_bars2 = 0;
2198 if(!Get("//composition[@name='forwardTOF_top1']/mposY[@volume='FTOC']/@ncopy",num_bars2)) return false;
2199 int num_single_end_bars2 = 0;
2200 if(!Get("//composition[@name='forwardTOF_south']/mposY[@volume='FTOH']/@ncopy",num_single_end_bars2)) return false;
2201
2202 int NLONGBARS = num_bars1 + num_bars2 + num_narrow_bars1 + num_narrow_bars2
2203 + num_narrower_bars1 + num_narrower_bars2;
2204 int NSHORTBARS = num_single_end_bars1 + num_single_end_bars2;
2205 int FIRSTSHORTBAR = num_bars1 + num_narrow_bars1 + num_narrower_bars1 + 1;
2206 int LASTSHORTBAR = FIRSTSHORTBAR + NSHORTBARS/2 - 1;
2207
2208 // load bar sizes
2209 //Get("//composition[@name='forwardTOF_bottom1']/mposY[@volume='FTOC']/@X_Y_Z",xyz_bar);
2210 if(!Get("//box[@name='FTOC' and sensitive='true']/@X_Y_Z", xyz_bar)) return false;
2211 double LONGBARLENGTH = xyz_bar[0];
2212 double BARWIDTH = xyz_bar[1];
2213 //Get("//composition[@name='forwardTOF_bottom1']/mposY[@volume='FTOH']/@X_Y_Z",xyz_bar);
2214 if(!Get("//box[@name='FTOH' and sensitive='true']/@X_Y_Z", xyz_bar)) return false;
2215 double SHORTBARLENGTH = xyz_bar[0];
2216
2217
2218 // load up the structure containing the parameters for the calling function
2219 paddle_params["NLONGBARS"] = NLONGBARS;
2220 paddle_params["NSHORTBARS"] = NSHORTBARS;
2221 paddle_params["BARWIDTH"] = BARWIDTH;
2222
2223 paddle_params["LONGBARLENGTH"] = LONGBARLENGTH;
2224 paddle_params["HALFLONGBARLENGTH"] = LONGBARLENGTH/2.;
2225 paddle_params["SHORTBARLENGTH"] = SHORTBARLENGTH;
2226 paddle_params["HALFSHORTBARLENGTH"] = SHORTBARLENGTH/2.;
2227
2228 paddle_params["FIRSTSHORTBAR"] = FIRSTSHORTBAR;
2229 paddle_params["LASTSHORTBAR"] = LASTSHORTBAR;
2230
2231 //cout << "In DGeometry::GetTOFPaddleParameters() ..." << endl;
2232 //for(auto el : paddle_params) {
2233 // std::cout << el.first << " " << el.second << endl;
2234 //}
2235
2236 return true;
2237}
2238
2239
2240//---------------------------------
2241// GetTOFPaddlePerpPositions
2242//---------------------------------
2243bool DGeometry::GetTOFPaddlePerpPositions(vector<double> &y_tof, vector<double> &y_widths) const
2244{
2245 // add in a dummy entry, since we are indexing by paddle number, which starts at 1
2246 // maybe change this some day?
2247 y_tof.push_back(0);
2248 y_widths.push_back(0);
2249
2250 // Next fill array of bar positions within a plane
2251 // y_tof[barnumber] gives y position in the center of the bar. [currently barnumber = 1 - 46]
2252 double y0,dy;
2253
2254 // load the number of bars
2255 int num_bars=1; // start counting at 1
2256 int num_bars1 = 0;
2257 Get("//composition[@name='forwardTOF_bottom1']/mposY[@volume='FTOC']/@ncopy",num_bars1);
2258 int num_narrow_bars1 = 0;
2259 Get("//composition[@name='forwardTOF_bottom2']/mposY[@volume='FTOX']/@ncopy",num_narrow_bars1);
2260 int num_single_end_bars1 = 0;
2261 Get("//composition[@name='forwardTOF_north']/mposY[@volume='FTOH']/@ncopy",num_single_end_bars1);
2262
2263 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2264 int num_narrower_bars1 = 0;
2265 Get("//composition[@name='forwardTOF_bottom3']/mposY[@volume='FTOL']/@ncopy",num_narrower_bars1);
2266 int num_narrower_bars2 = 0;
2267 Get("//composition[@name='forwardTOF_top3']/mposY[@volume='FTOL']/@ncopy",num_narrower_bars2);
2268 jgeom->SetVerbose(1); // reenable error messages
2269
2270 int num_narrow_bars2 = 0;
2271 Get("//composition[@name='forwardTOF_top2']/mposY[@volume='FTOX']/@ncopy",num_narrow_bars2);
2272 int num_bars2 = 0;
2273 Get("//composition[@name='forwardTOF_top1']/mposY[@volume='FTOC']/@ncopy",num_bars2);
2274 int num_single_end_bars2 = 0;
2275 Get("//composition[@name='forwardTOF_south']/mposY[@volume='FTOH']/@ncopy",num_single_end_bars2);
2276
2277 // First 19 long bars
2278 Get("//composition[@name='forwardTOF_bottom1']/mposY/@Y0",y0);
2279 Get("//composition[@name='forwardTOF_bottom1']/mposY/@dY",dy);
2280 vector<double>tof_bottom1;
2281 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_bottom1']/@X_Y_Z",tof_bottom1);
2282 for (int k=num_bars;k<num_bars+num_bars1;k++){
2283 y_tof.push_back(y0+tof_bottom1[1]+dy*double(k-num_bars));
2284 y_widths.push_back(dy);
2285 }
2286 num_bars+=num_bars1;
2287
2288 // two narrow long bars
2289 Get("//composition[@name='forwardTOF_bottom2']/mposY/@Y0",y0);
2290 Get("//composition[@name='forwardTOF_bottom2']/mposY/@dY",dy);
2291 vector<double>tof_bottom2;
2292 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_bottom2']/@X_Y_Z",tof_bottom2);
2293 for (int k=num_bars;k<num_bars+num_narrow_bars1;k++){
2294 y_tof.push_back(y0+tof_bottom2[1]+dy*double(k-num_bars));
2295 y_widths.push_back(dy);
2296 }
2297 num_bars+=num_narrow_bars1;
2298
2299 // two narrower long bars - added by upgrade
2300 if(num_narrower_bars1 > 0) {
2301 Get("//composition[@name='forwardTOF_bottom3']/mposY/@Y0",y0);
2302 Get("//composition[@name='forwardTOF_bottom3']/mposY/@dY",dy);
2303 vector<double>tof_bottom3;
2304 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_bottom3']/@X_Y_Z",tof_bottom3);
2305 for (int k=num_bars;k<num_bars+num_narrower_bars1;k++){
2306 y_tof.push_back(y0+tof_bottom3[1]+dy*double(k-num_bars));
2307 y_widths.push_back(dy);
2308 }
2309 num_bars+=num_narrow_bars1;
2310 }
2311
2312 // two short wide bars (4 wide in upgrade)
2313 Get("//composition[@name='forwardTOF_north']/mposY/@Y0",y0);
2314 Get("//composition[@name='forwardTOF_north']/mposY/@dY",dy);
2315 vector<double>tof_north;
2316 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_north']/@X_Y_Z",tof_north);
2317 for (int k=num_bars;k<num_bars+num_single_end_bars1;k++){
2318 y_tof.push_back(y0+tof_north[1]+dy*double(k-num_bars));
2319 y_widths.push_back(dy);
2320 }
2321 num_bars+=num_single_end_bars1;
2322
2323 // two narrower long bars - added by upgrade
2324 if(num_narrower_bars2 > 0) {
2325 Get("//composition[@name='forwardTOF_top3']/mposY/@Y0",y0);
2326 Get("//composition[@name='forwardTOF_top3']/mposY/@dY",dy);
2327 vector<double>tof_top3;
2328 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_top3']/@X_Y_Z",tof_top3);
2329 for (int k=num_bars;k<num_bars+num_narrower_bars2;k++){
2330 y_tof.push_back(y0+tof_top3[1]+dy*double(k-num_bars));
2331 y_widths.push_back(dy);
2332 }
2333 num_bars+=num_narrow_bars2;
2334 }
2335
2336 // two narrow long bars
2337 Get("//composition[@name='forwardTOF_top2']/mposY/@Y0",y0);
2338 Get("//composition[@name='forwardTOF_top2']/mposY/@dY",dy);
2339 vector<double>tof_top2;
2340 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_top2']/@X_Y_Z",tof_top2);
2341 for (int k=num_bars;k<num_bars+num_narrow_bars2;k++){
2342 y_tof.push_back(y0+tof_top2[1]+dy*double(k-num_bars));
2343 y_widths.push_back(dy);
2344 }
2345 num_bars+=num_narrow_bars2;
2346
2347 // Last 19 long bars
2348 Get("//composition[@name='forwardTOF_top1']/mposY/@Y0",y0);
2349 Get("//composition[@name='forwardTOF_top1']/mposY/@dY",dy);
2350 vector<double>tof_top1;
2351 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_top1']/@X_Y_Z",tof_top1);
2352 for (int k=num_bars;k<num_bars+num_bars2;k++){
2353 y_tof.push_back(y0+tof_top1[1]+dy*double(k-num_bars));
2354 y_widths.push_back(dy);
2355 }
2356 num_bars+=num_bars2;
Value stored to 'num_bars' is never read
2357
2358 /*
2359 // two more short wide bars - IGNORE FOR NOW, ASSUME SAME Y AS OTHER SINGLE ENDED
2360 Get("//composition[@name='forwardTOF_south']/mposY/@Y0",y0);
2361 Get("//composition[@name='forwardTOF_south']/mposY/@dY",dy);
2362 vector<double>tof_south;
2363 Get("//composition[@name='forwardTOF']/posXYZ[@volume='forwardTOF_south']/@X_Y_Z",tof_south);
2364 for (unsigned int k=45;k<47;k++){
2365 y_tof.push_back(y0+tof_south[1]+dy*double(k-45));
2366 }
2367 */
2368
2369 return true;
2370}
2371
2372//---------------------------------
2373// GetTargetZ
2374//---------------------------------
2375bool DGeometry::GetTargetZ(double &z_target) const
2376{
2377 // Default to nominal center of GlueX target
2378 z_target=65.;
2379
2380 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2381
2382 // Check GlueX target is defined
2383 bool gluex_target_exists = true;
2384 vector<double> xyz_vessel;
2385 vector<double> xyz_target;
2386 vector<double> xyz_detector;
2387 if(gluex_target_exists) gluex_target_exists = Get("//composition[@name='targetVessel']/posXYZ[@volume='targetTube']/@X_Y_Z", xyz_vessel);
2388 if(gluex_target_exists) gluex_target_exists = Get("//composition[@name='Target']/posXYZ[@volume='targetVessel']/@X_Y_Z", xyz_target);
2389 if(gluex_target_exists) gluex_target_exists = Get("//posXYZ[@volume='Target']/@X_Y_Z", xyz_detector);
2390 if(gluex_target_exists) {
2391 z_target = xyz_vessel[2] + xyz_target[2] + xyz_detector[2];
2392 jgeom->SetVerbose(1); // reenable error messages
2393 return true;
2394 }
2395
2396 // Check if CPP target is defined
2397 bool cpp_target_exists = true;
2398 vector<double> xyz_TGT0;
2399 vector<double> xyz_TARG;
2400 vector<double> xyz_TargetCPP;
2401 if(cpp_target_exists) cpp_target_exists = Get("//composition/posXYZ[@volume='TGT0']/@X_Y_Z", xyz_TGT0);
2402 if(cpp_target_exists) cpp_target_exists = Get("//composition/posXYZ[@volume='TARG']/@X_Y_Z", xyz_TARG);
2403 if(cpp_target_exists) cpp_target_exists = Get("//composition/posXYZ[@volume='TargetCPP']/@X_Y_Z", xyz_TargetCPP);
2404 if(cpp_target_exists) {
2405 z_target = xyz_TGT0[2] + xyz_TARG[2] + xyz_TargetCPP[2];
2406 jgeom->SetVerbose(1); // reenable error messages
2407 return true;
2408 }
2409
2410 // Check if PrimEx Be target is defined
2411 bool primex_target_exists = true;
2412 vector<double> xyz_BETG;
2413 if(primex_target_exists) primex_target_exists = Get("//composition[@name='targetVessel']/posXYZ[@volume='BETG']/@X_Y_Z", xyz_BETG);
2414 if(primex_target_exists) primex_target_exists = Get("//composition[@name='Target']/posXYZ[@volume='targetVessel']/@X_Y_Z", xyz_target);
2415 if(primex_target_exists) primex_target_exists = Get("//posXYZ[@volume='Target']/@X_Y_Z", xyz_detector);
2416 if(primex_target_exists) {
2417
2418 z_target = xyz_BETG[2] + xyz_target[2] + xyz_detector[2];
2419
2420 //cout << " PrimEx Be targer selected. Z target = = " << z_target << endl;
2421
2422 jgeom->SetVerbose(1); // reenable error messages
2423 return true;
2424 }
2425
2426 // Check if SRC carbon foils are defined. Return the center of the ladder
2427 vector<double>ladder_xyz;
2428 if (Get("//composition[@name='targetVessel']/posXYZ[@volume='carbonLadder']/@X_Y_Z",ladder_xyz)){
2429 Get("//composition[@name='Target']/posXYZ[@volume='targetVessel']/@X_Y_Z", xyz_target);
2430 Get("//posXYZ[@volume='Target']/@X_Y_Z", xyz_detector);
2431
2432 vector<double>foil_pos;
2433 Get("//composition[@name='carbonLadder']/posXYZ[@volume='carbonTarget1']/@X_Y_Z",foil_pos);
2434 z_target=0.5*foil_pos[2];
2435 Get("//composition[@name='carbonLadder']/posXYZ[@volume='carbonTarget8']/@X_Y_Z",foil_pos);
2436 z_target+=0.5*foil_pos[2];
2437 z_target+=xyz_target[2]+xyz_detector[2]+ladder_xyz[2];
2438
2439 jgeom->SetVerbose(1); // reenable error messages
2440 return true;
2441 }
2442
2443 // Only print warning for one thread whenever run number change
2444 static pthread_mutex_t empty_target_mutex = PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } };
2445 static set<int> empty_target_runs_announced;
2446
2447 // keep track of which runs we print out warnings for
2448 pthread_mutex_lock(&empty_target_mutex);
2449 bool empty_target_warning = false;
2450 if(empty_target_runs_announced.find(runnumber) == empty_target_runs_announced.end()){
2451 empty_target_warning = true;
2452 empty_target_runs_announced.insert(runnumber);
2453 }
2454 pthread_mutex_unlock(&empty_target_mutex);
2455
2456 if (empty_target_warning)
2457 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 " <<
2458 z_target << " cm" << endl;
2459
2460 jgeom->SetVerbose(1); // reenable error messages
2461
2462 return false;
2463}
2464
2465//---------------------------------
2466// GetTargetLength
2467//---------------------------------
2468bool DGeometry::GetTargetLength(double &target_length) const
2469{
2470
2471 target_length=0.;
2472 vector<double> zLength;
2473 jgeom->SetVerbose(0); // don't print error messages for optional detector elements
2474
2475 // Regular GlueX target
2476 if (Get("//section[@name='Target']/pcon[@name='LIH2']/real[@name='length']/[@value]", zLength)){
2477 target_length=zLength[0];
2478 jgeom->SetVerbose(1); // reenable error messages
2479 return true;
2480 }
2481
2482 // Liquid helium target
2483 if (Get("//section[@name='Target']/pcon[@name='LIHE']/real[@name='length']/[@value]", zLength)){
2484 target_length=zLength[0];
2485 jgeom->SetVerbose(1); // reenable error messages
2486 return true;
2487 }
2488
2489 // Beryllium target
2490 vector<double>rio_z;
2491 if (Get("//section[@name='Target']/tubs[@name='BETG']/@Rio_Z",rio_z)){
2492 target_length=rio_z[2];
2493 jgeom->SetVerbose(1); // reenable error messages
2494 return true;
2495 }
2496
2497 // Carbon foils for SRC; length is distance between first and last foil
2498 vector<double>foil_pos;
2499 if (Get("//composition[@name='carbonLadder']/posXYZ[@volume='carbonTarget1']/@X_Y_Z",foil_pos)){
2500 target_length-=foil_pos[2];
2501 Get("//composition[@name='carbonLadder']/posXYZ[@volume='carbonTarget8']/@X_Y_Z",foil_pos);
2502 target_length+=foil_pos[2];
2503 jgeom->SetVerbose(1); // reenable error messages
2504 return true;
2505 }
2506
2507 // Lead target for CPP
2508 if (Get("//section[@name='TargetCPP']/tubs[@name='TGT0']/@Rio_Z",rio_z)){
2509 target_length=rio_z[2];
2510 jgeom->SetVerbose(1); // reenable error messages
2511 return true;
2512 }
2513
2514 jgeom->SetVerbose(1); // reenable error messages
2515 return false;
2516}
2517
2518// Get vectors of positions and norm vectors for start counter from XML
2519bool DGeometry::GetStartCounterGeom(vector<vector<DVector3> >&pos,
2520 vector<vector<DVector3> >&norm
2521 ) const
2522{
2523
2524 JCalibration *jcalib = dapp->GetJCalibration(runnumber);
2525
2526 // Check if Start Counter geometry is present
2527 vector<double> sc_origin;
2528 bool got_sc = Get("//posXYZ[@volume='StartCntr']/@X_Y_Z", sc_origin);
2529 if(got_sc){
2530 // Offset from beam center
2531 vector<double>sc_origin_delta;
2532 Get("//posXYZ[@volume='startCntr']/@X_Y_Z", sc_origin_delta);
2533 double dx=sc_origin_delta[0];
2534 double dy=sc_origin_delta[1];
2535
2536 // z-position at upstream face of scintillators.
2537 double z0=sc_origin[2];
2538
2539 // Get rotation angles
2540 vector<double>sc_rot_angles;
2541 Get("//posXYZ[@volume='startCntr']/@rot", sc_rot_angles);
2542 double ThetaX=sc_rot_angles[0]*M_PI3.14159265358979323846/180.;
2543 double ThetaY=sc_rot_angles[1]*M_PI3.14159265358979323846/180.;
2544 Get("//posXYZ[@volume='StartCntr']/@rot", sc_rot_angles);
2545 //double ThetaX=sc_rot_angles[0]*M_PI/180.;
2546 //double ThetaY=sc_rot_angles[1]*M_PI/180.;
2547 double ThetaZ=sc_rot_angles[2]*M_PI3.14159265358979323846/180.;
2548
2549 // Get overall alignment shifts from CCDB
2550 map<string,double> sc_global_offsets;
2551 if (jcalib->Get("START_COUNTER/global_alignment_parms",sc_global_offsets)==false) {
2552 // translations
2553 dx += sc_global_offsets["SC_ALIGN_X"];
2554 dy += sc_global_offsets["SC_ALIGN_Y"];
2555 z0 += sc_global_offsets["SC_ALIGN_Z"];
2556
2557 // rotations
2558 ThetaX += sc_global_offsets["SC_ALIGN_ROTX"]*M_PI3.14159265358979323846/180.;
2559 ThetaY += sc_global_offsets["SC_ALIGN_ROTY"]*M_PI3.14159265358979323846/180.;
2560 ThetaZ += sc_global_offsets["SC_ALIGN_ROTZ"]*M_PI3.14159265358979323846/180.;
2561 }
2562
2563 double num_paddles;
2564 Get("//mposPhi[@volume='STRC']/@ncopy",num_paddles);
2565 double dSCdphi = M_TWO_PI6.28318530717958647692/num_paddles;
2566
2567 vector<vector<double> > sc_rioz;
2568 GetMultiple("//pgon[@name='STRC']/polyplane/@Rio_Z", sc_rioz);
2569
2570 // Get individual paddle alignment parameters
2571 vector< map<string,double> > sc_paddle_offsets;
2572 bool loaded_paddle_offsets = false;
2573 if (jcalib->Get("START_COUNTER/paddle_alignment_parms",sc_paddle_offsets)==false)
2574 loaded_paddle_offsets = true;
2575
2576 // Create vectors of positions and normal vectors for each paddle
2577 for (unsigned int i=0;i<30;i++){
2578 double phi=ThetaZ+dSCdphi*(double(i)+0.5);
2579 double sinphi=sin(phi);
2580 double cosphi=cos(phi);
2581 double r=0.5*(sc_rioz[0][0]+sc_rioz[0][1]);
2582 DVector3 oldray;
2583 // Rotate by phi and take into account the tilt
2584 double x=r*cosphi;//+dx;
2585 double y=r*sinphi;//+dy;
2586 DVector3 ray(x,y,sc_rioz[0][2]);
2587 ray.RotateX(ThetaX);
2588 ray.RotateY(ThetaY);
2589
2590 // Create stl-vectors to store positions and norm vectors
2591 vector<DVector3>posvec;
2592 vector<DVector3>dirvec;
2593 // Loop over radial/z positions describing start counter geometry from xml
2594 for(unsigned int k = 1; k < sc_rioz.size(); ++k){
2595 oldray=ray;
2596 r=0.5*(sc_rioz[k][0]+sc_rioz[k][1]);
2597 // Point in plane of scintillator
2598 x=r*cosphi;//+dx;
2599 y=r*sinphi;//+dy;
2600 ray.SetXYZ(x,y,sc_rioz[k][2]);
2601 ray.RotateX(ThetaX);
2602 ray.RotateY(ThetaY);
2603 // Apply alignment parameters
2604 if(loaded_paddle_offsets) {
2605 // allow for a maximum extent of the paddle in z
2606 double max_z = sc_paddle_offsets[i]["SC_MAX_Z"];
2607 if(ray.Z() > max_z) {
2608 ray.SetZ(max_z);
2609 }
2610 // allow for a modification of the bend angle of the paddle (18.5 deg from horizontal)
2611 // this should just be a perturbation around this angle, so assume a linear interpolation
2612 double delta_theta = sc_paddle_offsets[i]["SC_CURVE_THETA"]; // in degrees, r of curvature = 120 cm
2613 ray.SetX(ray.X()+delta_theta*1.65); // 1 degree ~ 1.65 cm in x
2614 ray.SetY(ray.Y()-delta_theta*0.55); // 1 degree ~ 0.55 cm in y
2615 }
2616 // Second point in the plane of the scintillator
2617 DVector3 ray2(r,10.,sc_rioz[k][2]);
2618 ray2.RotateZ(phi+0.5*dSCdphi*(1.+1./15.*((i>14)?29-i:i)));
2619 ray2.RotateX(ThetaX);
2620 ray2.RotateY(ThetaY);
2621 // Compute normal vector to plane
2622 DVector3 dir=(ray-oldray).Cross(ray2-oldray);
2623 dir.SetMag(1.);
2624 dirvec.push_back(dir);
2625 posvec.push_back(DVector3(oldray.X()+dx,oldray.Y()+dy,oldray.Z()+z0));
2626 }
2627 posvec.push_back(DVector3(ray.X()+dx,ray.Y()+dy,ray.Z()+z0)); //SAVE THE ENDPOINT OF THE LAST PLANE
2628 pos.push_back(posvec);
2629 norm.push_back(dirvec);
2630
2631 posvec.clear();
2632 dirvec.clear();
2633 }
2634
2635 }
2636 return got_sc;
2637}
2638