HYDRA_development_version
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
hgeommdc.cc
Go to the documentation of this file.
1 //*-- AUTHOR : Ilse Koenig
2 //*-- Created : 10/11/2003
3 
4 //_HADES_CLASS_DESCRIPTION
5 ///////////////////////////////////////////////////////////////////////////////
6 // HGeomMdc
7 //
8 // Class for geometry of MDC
9 //
10 // Creation of wires:
11 //
12 // The parameters (media, radia, wire distances, ...) to create wires
13 // (see class HGeomMdcWirePlanes) are read from a parameter ROOT file.
14 // For each wire the length and position is then calculated and an unique name
15 // generated.
16 // All wire planes (sensitive mother volumes) are implemented as TRD1, all
17 // wires as TUBE filled with a not-sentive medium. The GEANT/ROOT coordinate
18 // system of both shapes is indentical, but different from the HADES coordinate
19 // system.
20 //
21 // HADES coordinate system TRD1 coordinate system
22 //
23 // Line 1 xHades = xTrd1
24 // ---------- ^ (y) yHades = zTrd1
25 // \ Layer / | zHades = -yTrd1
26 // Line 0 -> \ MDC / <- Line 2 |
27 // \____/ |
28 // Line 3 |
29 // (x) <--------|-------------------
30 // 0,0
31 //
32 ///////////////////////////////////////////////////////////////////////////////
33 
34 #include "hgeommdc.h"
35 #include "hgeommdchit.h"
36 #include "hgeombuilder.h"
37 #include "hgeommedia.h"
38 #include "hgeommedium.h"
39 #include "hgeomnode.h"
40 #include "hgeommdcwireplanes.h"
41 #include "hgeommdcwire.h"
42 
43 #include "TFile.h"
44 
45 #include <iostream>
46 #include <iomanip>
47 
48 using namespace std;
49 
51 
52 HGeomMdc::HGeomMdc() {
53  // Constructor
54  fName="mdc";
55  maxSectors=6;
56  maxModules=4;
57  pHit=new HGeomMdcHit(this);
58  wn0=33; wn1=0; wn2=0; wn3=-1; // first name will be X000
59  memcpy(wnbuf,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",36);
60 }
61 
62 const Char_t* HGeomMdc::getModuleName(Int_t m) {
63  // Return the module name in plane m
64  sprintf(modName,"DR%iM",m+1);
65  return modName;
66 }
67 
68 const Char_t* HGeomMdc::getEleName(Int_t m) {
69  // Return the element name in plane m
70  sprintf(eleName,"D%i",m+1);
71  return eleName;
72 }
73 
74 Bool_t HGeomMdc::createAdditionalGeometry(HGeomBuilder* builder, const TString& paramFile, HGeomMedia* media) {
75  // reads wire plane parameters from file and creates the wires
76  Bool_t rc = kTRUE;
77  if (builder && paramFile.Length() > 0) {
78  TFile* file = new TFile(paramFile.Data(),"READ");
79  if (file==NULL || file->IsOpen()== kFALSE) {
80  Error("createAdditionalGeometry", "Parameter file %s not found", paramFile.Data());
81  return kFALSE;
82  }
83  file->cd();
84  HGeomMdcWirePlanes *mdcWirePlanes = (HGeomMdcWirePlanes*)file->Get("HGeomMdcWirePlanes");
85  if (mdcWirePlanes) {
86  //mdcWirePlanes->printWirePlanes();
87  vector<HGeomMdcWirePlane>& pWirePlanes = mdcWirePlanes->getWirePlanes();
88  Int_t totNumWires=0;
89  for (UInt_t np=0; np<pWirePlanes.size(); np++) {
90  HGeomMdcWirePlane& plane = pWirePlanes[np];
91  HGeomNode* pMother=getVolume(plane.planeName.Data());
92  if (pMother==NULL || pMother->isActive()==kFALSE) continue;
93  Double_t planeX[4], planeY[4];
94  for (Int_t i=0; i<4; i++) {
95  HGeomVector* point = pMother->getPoint(i);
96  planeX[i] = point->getX();
97  planeY[i] = point->getY();
98  }
99  Int_t medId[2] = {-1,-1};
100  for (Int_t i = 0; i <= plane.planeType && rc; i++) {
101  HGeomMedium* medium = media->getMedium(plane.wireMedium[i]);
102  if (medium) {
103  medId[i] = medium->getMediumIndex();
104  if (medId[i] <= 0) medId[i] = builder->createMedium(medium);
105  if (medId[i] <= 0) {
106  Error("createAdditionalGeometry",
107  "Medium %s not created",plane.wireMedium[i].Data());
108  rc = kFALSE;
109  }
110  } else {
111  Error("createAdditionalGeometry",
112  "Medium %s not found in list of media",plane.wireMedium[i].Data());
113  rc = kFALSE;
114  }
115  }
116  // --------------------------------------------------------------------
117  // create cathode wires
118  if (rc && plane.planeType == 0) {
119 
120  Float_t wireDist = plane.wireDist;
121  Float_t halfDist = wireDist * 0.5;
122  Float_t radius = plane.wireRadius[0];
123  Double_t posX = 0., posY = 0., posZ = 0.; // position relative to center of plane
124  Double_t at = (planeY[1] - planeY[0]) / (planeX[1] - planeX[0]);
125  Double_t bt = planeY[0] - at * planeX[0];
126  Double_t halfLengthCenter = (planeY[1] - planeY[0]) * 0.5; // central wire at x = 0.
127  TString wireName;
128  generateWireName(wireName);
129  Int_t wireNum = 0;
130  Int_t copyNum = 1;
131  //
132  // central part of cathode plane, wires are copies of central wire
133  HGeomMdcWire* pWire = NULL;
134  Int_t arrIndex = -1;
135  do {
136  copyNum = wireNum + 1;
137  arrIndex = addWireObject(wireNum, wireName, copyNum, 0, radius, halfLengthCenter, posX, posY, posZ);
138  if (wireNum == 0) {
139  pWire = wireObjects[arrIndex];
140  } else {
141  wireObjects[arrIndex]->setCopyNode(pWire); // needed to create copy nodes in ROOT
142  }
143  wireNum++;
144  posX += wireDist;
145  } while ((posX+radius) <= planeX[0]);
146  Int_t maxCopyNumLeft = copyNum;
147  //
148  // left part of cathode plane (all with copyNum 1)
149  copyNum = 1;
150  do {
151  generateWireName(wireName);
152  // calc half-length and position
153  Double_t y = at * (posX + radius) + bt;
154  Double_t halfLength = (planeY[1] - y) / 2.;
155  posZ = halfLengthCenter - halfLength;
156  addWireObject(wireNum, wireName, copyNum, 0, radius, halfLength, posX, posY, posZ);
157  wireNum++;
158  posX += wireDist;
159  } while ((posX+halfDist) < planeX[1]);
160  Int_t maxInd = wireObjects.size();
161  //
162  // create all left side wires
163  Int_t rotInd = 0; // no rotation needed for cathode wires
164  for (Int_t i=0; i<maxInd && rc; i++) {
165  pWire = wireObjects[i];
166  copyNum = pWire->getCopyNumber();
167  if (copyNum == 1) {
168  rc = builder->createVolume(pWire,medId[0]);
169  if (!rc) {
170  Error("createAdditionalGeometry",
171  "Plane %s wire %i not created",plane.planeName.Data(),i);
172  break;
173  }
174  }
175  rc = builder->positionNode(pWire,pMother,rotInd);
176  if (!rc) {
177  Error("createAdditionalGeometry",
178  "Plane %s wire %i not positioned",plane.planeName.Data(),i);
179  }
180  }
181  //
182  // create all right side wires starting from the middle (without central wire)
183  for (Int_t i=1; i<maxInd && rc; i++) {
184  pWire = wireObjects[i];
185  copyNum = pWire->getCopyNumber();
186  if (copyNum > 1) {
187  copyNum += maxCopyNumLeft -1;
188  } else {
189  copyNum += 1;
190  }
191  // change a left side wire to a right side wire
192  Float_t* wirePos = pWire->getPosition();
193  wirePos[0] *= -1.;
194  pWire->setWireNumber(wireNum);
195  pWire->setCopyNumber(copyNum);
196  rc = builder->positionNode(pWire,pMother,rotInd);
197  wireNum++;
198  }
199  //cout<<"***** Plane: "<<plane.planeName<<" Wires created: "<<wireNum<<endl;
200  totNumWires += wireNum;
201  clearWireObjects();
202  } // cathode plane
203  //
204  // --------------------------------------------------------------------
205  // create field (even wire number) and sens wires (odd wire number)
206  if (rc && plane.planeType == 1) {
207  //
208  // calculate and create GEANT rotation matrix for wires in the TRD1 coordinate system
209  Double_t wireOrient = -plane.wireOrient; // looking in reverse z-direction
210  Double_t sinWireOr = TMath::Sin(wireOrient*TMath::DegToRad());
211  Double_t cosWireOr = TMath::Cos(wireOrient*TMath::DegToRad());
212  Double_t arr[] = {sinWireOr, 0., cosWireOr, 0., 1., 0., -cosWireOr, 0., sinWireOr};
213  HGeomRotation rotMatrix;
214  rotMatrix.setMatrix(arr);
215  Int_t rotInd = builder->createRotation(&rotMatrix);
216  //
217  // calculate parameters relative to plane center
218  Double_t planeCenter[2];
219  planeCenter[0] = (planeX[0] + planeX[1] + planeX[2] + planeX[3]) * .25;
220  planeCenter[1] = (planeY[0] + planeY[1] + planeY[2] + planeY[3]) * .25;
221  for (Int_t i=0; i<4; i++) {
222  planeX[i] -= planeCenter[0];
223  planeY[i] -= planeCenter[1];
224  }
225  Double_t wireOffset = (plane.centralWireNr - 1) * plane.wireDist;
226  //
227  // reduce plane size for calculation to avoid extrusions of wire edges
228  Double_t at[4], bt[4]; // border lines of plane
229  Double_t radius = plane.wireRadius[0];
230  at[0] = (planeY[1] - planeY[0]) / (planeX[1] - planeX[0]);
231  Double_t dy = radius * cosWireOr;
232  Double_t dx1 = dy / at[0];
233  Double_t dx2 = 0;
234  if (wireOrient > 0.) {
235  dx2 = radius * (sinWireOr + cosWireOr / at[0]); // larger extrusion on left side
236  } else {
237  dx2 = -radius * (sinWireOr - cosWireOr / at[0]); // larger extrusion on right side
238  }
239  planeX[0] = planeX[0] + dx1 - dx2;
240  planeY[0] = planeY[0] + dy;
241  planeX[1] = planeX[1] - dx1 - dx2;
242  planeY[1] = planeY[1] - dy;
243  planeX[2] = -planeX[1];
244  planeY[2] = planeY[1];
245  planeX[3] = -planeX[0];
246  planeY[3] = planeY[0];
247  //
248  // calculate lines
249  for (Int_t i1=0; i1<4; i1++) {
250  Int_t i2 = i1 + 1;
251  if (i2==4) i2=0;
252  at[i1] = (planeY[i2] - planeY[i1]) / (planeX[i2] - planeX[i1]);
253  bt[i1] = planeY[i1] - at[i1] * planeX[i1];
254  //cout<<"line "<<i1<<" at: "<<at[i1]<<" bt: "<<bt[i1]<<endl;
255  }
256  //
257  // loop on wires
258  Double_t a = TMath::Tan(wireOrient*TMath::DegToRad());
259  Int_t numWiresPlane=0;
260  for(Int_t wireNum=0; wireNum<plane.numWires; wireNum++) {
261  Int_t wireType = wireNum%2;
262  Float_t radius = plane.wireRadius[wireType];
263  //
264  // calculation of wire length
265  Double_t yWire = wireNum * plane.wireDist - wireOffset;
266  Double_t b = yWire/cosWireOr - planeCenter[1];
267  Double_t x1 = (bt[0]-b)/(a-at[0]); // Xb line 0
268  Double_t x2 = (bt[2]-b)/(a-at[2]); // Xe line 2
269  Double_t y1 = a*x1+b; // Yb
270  Double_t y2 = a*x2+b; // Ye
271  Int_t nLine1 = (x1>=planeX[0] && x1<=planeX[1] && y1>=planeY[0] && y1<=planeY[1]) ? 0:-1;
272  Int_t nLine2 = (x2<=planeX[3] && x2>=planeX[2] && y2>=planeY[3] && y2<=planeY[2]) ? 2:-1;
273  if(nLine1<0 && nLine2 <0) {
274  // Warning("fillCont","%s: wire %i is out of layer.",vname.Data() , wireNum);
275  continue;
276  }
277  if(nLine1<0) {
278  x1 = (bt[1]-b)/(a-at[1]); // Xb line 1
279  if(x1<planeX[2]) x1 = (bt[3]-b)/(a-at[3]); // Xb line 3
280  y1 = a*x1+b; // Yb
281  } else if(nLine2<0) {
282  x2 = (bt[1]-b)/(a-at[1]); // Xe line 1
283  if(x2>planeX[1]) x2 = (bt[3]-b)/(a-at[3]); // Xe line 3
284  y2 = a*x2+b; // Ye
285  }
286  Double_t wireLength = TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
287  Double_t posX = (x2 + x1) * .5; // position in TRD1 coordinate system
288  Double_t posY = 0.;
289  Double_t posZ = (y2 + y1) * .5;
290  //cout<<wireNum<<" "<<yWire<<" "<<wireLength<<" "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<" "<<posX<<" "<<posZ<<endl;
291  //
292  // create and position wire
293  TString wireName;
294  generateWireName(wireName);
295  HGeomMdcWire wire(wireNum, wireName, 1, wireType, radius, wireLength * 0.5, posX, posY, posZ);
296  rc = builder->createVolume(&wire, medId[wireType]);
297  if (!rc) {
298  Error("createAdditionalGeometry",
299  "Plane %s wire %i not created",plane.planeName.Data(),wireNum);
300  break;
301  }
302  rc = builder->positionNode(&wire,pMother,rotInd);
303  if (!rc) {
304  Error("createAdditionalGeometry",
305  "Plane %s wire %i not positioned",plane.planeName.Data(),wireNum);
306  }
307  numWiresPlane++;
308  } //loop on wires
309  totNumWires += numWiresPlane;
310  //cout<<"***** Plane: "<<plane.planeName<<" Wires created: "<<numWiresPlane<<endl;
311  } // senswire plane
312  if (rc) builder->fillMdcCommonBlock(pMother);
313  } // loop on planes
314  cout<<" Wires created: "<<totNumWires<<endl;
315  delete mdcWirePlanes;
316  mdcWirePlanes = NULL;
317  } else {
318  Warning("createAdditionalGeometry", "HGeomMdcWires not found in parameter file %s", paramFile.Data());
319  }
320  file->Close();
321  }
322  return rc;
323 }
324 
325 void HGeomMdc::generateWireName(TString& vName) {
326  // generates the wire name
327  if (wn3<35) wn3++;
328  else {
329  wn3 = 0;
330  if (wn2<35) wn2++;
331  else {
332  wn2 = 0;
333  if (wn1<35) wn1++;
334  else {
335  wn1 = 0;
336  wn0++;
337  }
338  }
339  }
340  vName.Form("%c%c%c%c",wnbuf[wn0],wnbuf[wn1],wnbuf[wn2],wnbuf[wn3]);
341 }
342 
344  // deletes objects in working array and sets pointer to 0.
345  // cleares the vector.
346  for(UInt_t i = 0; i < wireObjects.size(); i ++) {
347  if (wireObjects[i]) {
348  delete wireObjects[i];
349  wireObjects[i] = 0;
350  }
351  }
352  wireObjects.clear();
353 }
354 
355 Int_t HGeomMdc::addWireObject(Int_t wn, TString& wname, Int_t cn, Int_t wtype, Float_t radius,
356  Double_t hlen, Double_t xpos, Double_t ypos, Double_t zpos) {
357  // creates a wire objects and adds it in the working array
358  // returns the array index
359  HGeomMdcWire* wire = new HGeomMdcWire(wn, wname, cn, wtype, radius, hlen, xpos, ypos, zpos);
360  wireObjects.push_back(wire);
361  return (wireObjects.size()-1);
362 }
Int_t getCopyNumber()
Definition: hgeommdcwire.h:48
Bool_t createAdditionalGeometry(HGeomBuilder *, const TString &, HGeomMedia *)
Definition: hgeommdc.cc:74
virtual void fillMdcCommonBlock(HGeomNode *)
Definition: hgeombuilder.h:30
HGeomMedium * getMedium(const Char_t *)
Definition: hgeommedia.cc:33
virtual Bool_t positionNode(HGeomMdcWire *, HGeomNode *, Int_t)
Definition: hgeombuilder.h:29
const Char_t * getEleName(Int_t)
Definition: hgeommdc.cc:68
ClassImp(HGeomMdc) HGeomMdc
Definition: hgeommdc.cc:50
virtual Bool_t createVolume(HGeomMdcWire *, Int_t)
Definition: hgeombuilder.h:27
Float_t * getPosition()
Definition: hgeommdcwire.h:52
void setCopyNode(HGeomMdcWire *p)
Definition: hgeommdcwire.h:44
void clearWireObjects()
Definition: hgeommdc.cc:343
void setMatrix(const Double_t *)
Definition: hgeomrotation.h:61
void generateWireName(TString &vName)
Definition: hgeommdc.cc:325
void setWireNumber(Int_t wn)
Definition: hgeommdcwire.h:42
Bool_t rc
HGeomVector * getPoint(const Int_t n)
Definition: hgeomvolume.h:52
virtual Int_t createMedium(HGeomMedium *)=0
const Char_t * getModuleName(Int_t)
Definition: hgeommdc.cc:62
vector< HGeomMdcWirePlane > & getWirePlanes()
Int_t getMediumIndex()
Definition: hgeommedium.h:36
Bool_t isActive()
Definition: hgeomnode.h:46
Int_t addWireObject(Int_t, TString &, Int_t, Int_t, Float_t, Double_t, Double_t, Double_t, Double_t)
Definition: hgeommdc.cc:355
void setCopyNumber(Int_t cn)
Definition: hgeommdcwire.h:43
Double_t getX() const
Definition: hgeomvector.h:22
virtual Int_t createRotation(HGeomRotation *)
Definition: hgeombuilder.h:28
Double_t getY() const
Definition: hgeomvector.h:23