StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StiDetector.cxx
1 #include <math.h>
2 #include "Stiostream.h"
3 #include <string>
4 #include <map>
5 #include "TError.h"
6 #include "TVector3.h"
7 #include "StiMaterial.h"
8 #include "StiShape.h"
9 #include "StiPlanarShape.h"
10 #include "StiCylindricalShape.h"
11 #include "StiPlacement.h"
12 #include "StiDetectorContainer.h"
13 #include "StiDetector.h"
14 #include "Sti/StiToolkit.h"
15 #include "StiUtilities/StiDebug.h"
16 #include "StiMapUtilities.h"
17 
18 int StiDetector::mgIndex=0;
19 double StiDetector::mgValue[2]={0};
20 
21 
22 //______________________________________________________________________________
23 StiDetector::StiDetector()
24 {
25  reset();
26 }
27 //______________________________________________________________________________
28 void StiDetector::reset()
29 {
30  setName("");
31  memset(mBeg,0,mEnd-mBeg+1);
32  _key1 = _key2 = -1;
33  _groupId = -1;
34 }
35 
36 //______________________________________________________________________________
37 StiDetector::~StiDetector()
38 {}
39 
40 //______________________________________________________________________________
41 void StiDetector::copy(StiDetector &detector){
42 
44 
45  gas = detector.getGas();
46  material = detector.getMaterial();
47  shape = detector.getShape();
48  placement = detector.getPlacement();
49  _cos = detector._cos;
50  _sin = detector._sin;
51  setName(detector.getName());
52 }
53 
54 //______________________________________________________________________________
55 ostream& operator<<(ostream& os, const StiDetector& d)
56 {
57  os << "StiDetector:" << endl
58  << d.getName()
59  << "\t_groupId: " << d.getGroupId()
60  <<"\tR:"<<d.getPlacement()->getNormalRadius()<<"cm\tA:"
61  <<d.getPlacement()->getNormalRefAngle()<< " radians" << endl;
62 
63  if (d.material)
64  os << *d.material;
65 
66  if (d.shape)
67  os << *d.shape;
68 
69  if (d.placement)
70  os << *d.placement;
71 
72  return os;
73 }
74 //______________________________________________________________________________
75 int StiDetector::splitIt(StiDetVect &vect,double dXdY,int nMax)
76 {
77 static int nCall=0; nCall++;
78 
79 
80  vect.resize(1);
81  vect[0]=this;
82  assert(shape);
83  int iShape = shape->getShapeCode();
84  float deltaX = shape->getThickness();
85  float halfZ = shape->getHalfDepth();
86  float halfY = shape->getHalfWidth();
87  float angle = shape->getOpeningAngle();
88  float nRadius = placement->getNormalRadius();
89  if (iShape >= kCylindrical) nRadius = shape->getOuterRadius()-deltaX/2;
90 
91  if (nRadius < deltaX/2) { // non splitable
92  printf("StiDetector::splitIt %s Non splitable Rnormal < thickness/2 %g %g\n"
93  ,getName().c_str(),nRadius,deltaX/2);
94  return 1;
95  }
96  int ny = deltaX/(halfY*2*dXdY)+0.5;
97  int nz = deltaX/(halfZ*2*dXdY)+0.5;
98  int nSplit = (ny>nz)? ny:nz;
99  if (nSplit<=1) return 1;
100  if (nSplit>nMax) nSplit=nMax;
101 
102 // OK, we mast split it.
103 
104  vect.clear();
105  float dX = deltaX/nSplit;
106  double sumWeight = 0;
107  for (int iSplit=0; iSplit<nSplit; iSplit++)
108  {
109  float xc = -deltaX/2 +dX/2+iSplit*dX;
110 // Create small part of detector
111  StiDetector *det = StiToolkit::instance()->getDetectorFactory()->getInstance();
112  det->copy(*this);
113  TString ts(getName());
114  if (iSplit) { ts+="_"; ts+=iSplit;}
115  det->setName(ts.Data());
116 // Create shape
117  ts = shape->getName();
118  if (iSplit) { ts+="_"; ts+=iSplit;}
119  StiShape *myShape =0;
120  float myRadius = nRadius+xc;
121 assert(myRadius>1e-2 && myRadius < 1e3);
122  if (iShape==kPlanar) {//Planar shape
123  myShape = new StiPlanarShape(ts.Data(),halfZ,dX,halfY);
124 
125  } else if (iShape>=kCylindrical) {//Cylinder shape
126  myShape = new StiCylindricalShape(ts.Data(),halfZ,dX,myRadius+dX/2,angle);
127 
128  } else { assert(0 && "Wrong shape type");}
129 
130 // Create placement
131  StiPlacement *place = new StiPlacement;
132  *place = *placement;
133  place->setNormalRep(placement->getNormalRefAngle(),myRadius,placement->getNormalYoffset());
134  det->setShape(myShape);
135  place->setLayerRadius(myRadius);
136  det->setPlacement(place);
137  sumWeight += det->getWeight();
138  vect.push_back(det);
139  }
140  this->copy(*vect[0]);
141  this->setName(vect[0]->getName());
142 // delete vect[0];
143  StiToolkit::instance()->getDetectorFactory()->free(vect[0]);
144  vect[0] = this;
145 // if (vect.size()>1) {
146 // printf("StiDetector::splitIt %s is splitted into %d peaces\n",getName().c_str(),vect.size());}
147 // assert(fabs(startWeight-sumWeight)<1e-3*startWeight);
148 
149 
150  return vect.size();
151 }
152 //______________________________________________________________________________
153 double StiDetector::getVolume() const
154 {
155 return shape->getVolume();
156 }
157 //______________________________________________________________________________
158  double StiDetector::getWeight() const
159 {
160 return shape->getVolume()*material->getDensity();
161 }
162 //______________________________________________________________________________
163 int StiDetector::insideL(const double xl[3],int mode,double fakt) const
164 {
165 static int nCall = 0; nCall++;
166 if (!mode) mode = 1;
167 double rN = placement->getNormalRadius();
168 double acc = rN*(fakt-1);
169 if (acc<0.1) acc = 0.1;
170 if (acc>10.) acc = 10.;
171 
172 
173 double thick = shape->getThickness();
174 do {
175  if (shape->getShapeCode()==1) { //Planar
176  if (mode&1) {
177  mgIndex = 1;
178  mgValue[1] = thick/2;
179  mgValue[0] = fabs(xl[0]-rN)-mgValue[1];
180  if (mgValue[0]>acc) return 0;
181  }
182  if (mode&2) {
183  mgIndex = 2;
184  double y = xl[1]-placement->getNormalYoffset();
185  mgValue[1] = shape->getHalfWidth();
186  mgValue[0] = fabs(y)-mgValue[1];
187  if (mgValue[0]>acc) return 0;
188  }
189  } else {
190  if (mode&1) {
191  mgIndex = 1;
192  mgValue[1] = thick/2;
193  double rxy = sqrt(xl[0]*xl[0]+xl[1]*xl[1]);
194  mgValue[0] = (fabs(rxy-rN)-mgValue[1]);
195  if (mgValue[0]>acc) return 0;
196  }
197 
198  if (mode&2) {
199  mgIndex = 2;
200  double ang = atan2(xl[1],xl[0]);
201  if (ang<-M_PI) ang +=M_PI*2;
202  if (ang> M_PI) ang -=M_PI*2;
203  mgValue[1] = shape->getOpeningAngle()/2;
204  mgValue[0] = (fabs(ang)-mgValue[1]);
205  if (mgValue[0]>acc/rN) return 0;
206  }
207  }
208  if (!(mode&4)) return 1;
209  mgIndex = 3;
210  mgValue[1] = shape->getHalfDepth();
211  double z = xl[2]-placement->getZcenter();
212  mgValue[0] = (fabs(z)-mgValue[1]);
213  if (mgValue[0]>acc && fabs(xl[2]) > 100) return 0;
214 
215  return 1;
216  } while(0);
217  return 0;
218 }
219 
226 void StiDetector::setProperties(std::string name, StiIsActiveFunctor* activeFunctor,
227  StiShape* shape, StiPlacement* placement, StiMaterial* gas, StiMaterial* material)
228 {
229  setName(name.c_str());
230  setIsActive(activeFunctor);
231  setShape(shape);
232  setPlacement(placement);
233  setGas(gas);
234  setMaterial(material);
235 }
236 //______________________________________________________________________________
237 int StiDetector::insideG(const double xl[3],int mode,double fakt) const
238 {
239  TVector3 xg(xl);
240  double alfa = getPlacement()->getNormalRefAngle();
241  xg.RotateZ(-alfa);
242  return insideL(&xg[0],mode,fakt);
243 }
244 //______________________________________________________________________________
245 void StiDetector::getDetPlane(double plane[4]) const
246 {
247  plane[0] = - getPlacement()->getNormalRadius();
248  plane[1] = _cos;
249  plane[2] = _sin;
250  plane[3] = 0.;
251 }
void setProperties(std::string name, StiIsActiveFunctor *activeFunctor, StiShape *shape, StiPlacement *placement, StiMaterial *gas, StiMaterial *material)
double _cos
Convenience storage of cos(refAngle)
Definition: StiDetector.h:132
int _groupId
Detector group identifier.
Definition: StiDetector.h:136
StiIsActiveFunctor * isActiveFunctor
Definition: StiDetector.h:114
virtual void free(Abstract *obj)=0
Free an object for reuse.
StiMaterial * material
Discrete scatterer attributes.
Definition: StiDetector.h:122
StiPlacement * placement
Physical position and orientation of this detector or volume.
Definition: StiDetector.h:127
virtual Abstract * getInstance()=0
Get a pointer to instance of objects served by this factory.
StiMaterial * gas
Continuous scatter attributes.
Definition: StiDetector.h:120
function object for determine a detector&#39;s active regions
Abstract interface for a STI toolkit.
double _sin
Convenience storage of sin(refAngle)
Definition: StiDetector.h:134
StiShape * shape
Physical Shape attribute of this detector or voloume.
Definition: StiDetector.h:125
void setName(const string &newName)
Set the name of the object.
Definition: Named.cxx:15
double getDensity() const
Get the material density in grams/cubic centimeter.
Definition: StiMaterial.h:35
const string & getName() const
Get the name of the object.
Definition: Named.cxx:22