001 #include "MuonGeoModel/MultiLayer.h"
002 #include "MuonGeoModel/DriftTube.h"
003 #include "MuonGeoModel/MYSQL.h"
004 #include "MuonGeoModel/Mdt.h"
005 #include "MuonGeoModel/MDT_Technology.h"
006 #include "GeoModelKernel/GeoXF.h"
007 #include "GeoModelKernel/GeoTrd.h"
008 #include "GeoModelKernel/GeoLogVol.h"
009 #include "GeoModelKernel/GeoPhysVol.h"
010 #include "GeoModelKernel/GeoFullPhysVol.h"
011 #include "GeoModelKernel/GeoMaterial.h"
012 #include "GeoModelKernel/GeoNameTag.h"
013 #include "GeoModelKernel/GeoSerialDenominator.h"
014 #include "GeoModelKernel/GeoSerialTransformer.h"
015 #include "GeoModelKernel/GeoTransform.h"
016 #include "GeoModelKernel/GeoIdentifierTag.h"
017 #include "GeoModelKernel/GeoSerialIdentifier.h"
018 #include "CLHEP/Geometry/Transform3D.h"
019 #include "CLHEP/GenericFunctions/AbsFunction.hh"
020 #include "CLHEP/GenericFunctions/Variable.hh"
021
022 #include "GeoModelKernel/GeoShape.h"
023 #include "GeoModelKernel/GeoShapeShift.h"
024 #include "GeoModelKernel/GeoShapeUnion.h"
025 #include "GeoModelKernel/GeoShapeSubtraction.h"
026 #include "GeoModelKernel/GeoTube.h"
027
028
029 #include <vector>
030 #include <cassert>
031 using namespace GeoXF;
032
033 #define verbose_multilayer false
034
035 namespace MuonGM {
036
037 MultiLayer::MultiLayer(std::string n): DetectorElement(n)
038 {
039 MYSQL* mysql = MYSQL::GetPointer();
040 MDT* md = (MDT*)mysql->GetTechnology(name);
041 if (md != NULL) {
042 nrOfLayers = md->numOfLayers;
043 mdtthickness = md->totalThickness;
044 tubePitch = md->pitch;
045 for (int i = 0; i < 4; i++) {
046 yy[i] = 0.;
047 xx[i] = 0.;
048 }
049
050 for (int i = 0; i < nrOfLayers; i++) {
051 yy[i] = md->y[i];
052 xx[i] = md->x[i];
053 }
054 nrOfSteps=1;
055
056 } else {
057 std::cerr << "Multilayer constructor - a problem here !!! MDT named " << name
058 << " not found \n Cannot init correctly !";
059 assert(0);
060 }
061 }
062
063
064 GeoFullPhysVol* MultiLayer::build()
065 {
066 DriftTube tube(name+" DriftTube");
067 double eps = 0.001;
068 double tuberad = tube.outerRadius;
069 if (verbose_multilayer)
070 std::cout << " MultiLayer::build of " << name
071 << " logVolName = " << logVolName
072 << " tube radius, pitch = " << tuberad
073 << " , " << tubePitch << std::endl;
074
075 const GeoShape* slay = NULL;
076 const GeoShape* sfoamup = NULL;
077 const GeoShape* sfoamlow = NULL;
078
079 double foamthicknesslow = yy[0] - tuberad;
080 double foamthicknessup;
081 if (yy[3]) foamthicknessup = mdtthickness - (yy[3]+tuberad);
082 else foamthicknessup = mdtthickness - (yy[2]+tuberad);
083
084 if (foamthicknessup > foamthicknesslow) {
085 foamthicknesslow = 0.;
086 if (fabs(foamthicknessup - 15*mm) < 0.1) foamthicknessup = 15*mm;
087 else if (fabs(foamthicknessup - 30.75*mm) < 0.1) foamthicknessup = 30.75*mm;
088 else if (fabs(foamthicknessup - 30.00*mm) < 0.1) foamthicknessup = 30.00*mm;
089 else {
090 std::cout << " problem with thickness of foam in LogVolName "
091 << logVolName << std::endl;
092 }
093
094 } else {
095 foamthicknessup = 0.;
096 if (fabs(foamthicknesslow - 15*mm) < 0.1) foamthicknesslow = 15*mm;
097 else if (fabs(foamthicknesslow - 30.75*mm) < 0.1) foamthicknesslow = 30.75*mm;
098 else if (fabs(foamthicknesslow - 30.00*mm) < 0.1) foamthicknesslow = 30.00*mm;
099 else {
100 std::cout << " problem with thickness of foam in LogVolName "
101 << logVolName << std::endl;
102 }
103 }
104
105
106 double TrdDwoverL= (longWidth-width)/length;
107 if (cutoutNsteps == 1) {
108
109 slay = new GeoTrd(mdtthickness/2, mdtthickness/2, width/2,
110 longWidth/2, length/2);
111 } else {
112
113 if (verbose_multilayer) std::cout << name << " has " << cutoutNsteps
114 << " cutout steps " << std::endl;
115 double submlthick = mdtthickness/2.;
116 double submlwidths = width/2.;
117 double submlwidthl = width/2.;
118 double lengthPos = 0.;
119 double sum_len = 0;
120
121 for (int isub = 0; isub < cutoutNsteps; isub++) {
122 if (verbose_multilayer) std::cout << " cutout region " << isub << " has "
123 << cutoutNtubes[isub] << " tubes " << std::endl;
124 if (cutoutNtubes[isub] <= 0) {
125 std::cout << " Skipping cutout region " << isub << " with " << cutoutNtubes[isub]
126 << " tubes in LogVolName " << logVolName << std::endl;
127 continue;
128 }
129
130 double submllength = (cutoutNtubes[isub]*tubePitch)/2.;
131 if (cutoutFullLength[isub] && isub != cutoutNsteps - 1) submllength += tubePitch/4.;
132 submlwidthl += submllength*TrdDwoverL;
133 lengthPos = -length/2. + sum_len + submllength;
134 sum_len += 2.*submllength;
135 double widthPos = cutoutXtubes[isub];
136 HepTransform3D submlpos = HepTranslate3D(0.,widthPos,lengthPos);
137
138 const GeoTrd* tempSLay = NULL;
139 const GeoShape* tempSLay1 = NULL;
140 const GeoTrd* tempSFoamup = NULL;
141 const GeoShape* tempSFoamup1 = NULL;
142 const GeoTrd* tempSFoamlow = NULL;
143 const GeoShape* tempSFoamlow1 = NULL;
144
145 if (submlthick*submlwidthl*submllength > 0) {
146 if (verbose_multilayer) std::cout << " LogVolName " << logVolName
147 << " cut step " << isub
148 << " thick = " << submlthick
149 << " short width = " << submlwidths
150 << " long width = " << submlwidthl
151 << " length = " << submllength
152 << " translated to " << widthPos
153 << " , " << lengthPos << std::endl;
154 if (cutoutFullLength[isub]) {
155 tempSLay = new GeoTrd(submlthick, submlthick, submlwidths,
156 submlwidthl, submllength);
157 } else {
158 tempSLay = new GeoTrd(submlthick, submlthick, cutoutTubeLength[isub]/2.,
159 cutoutTubeLength[isub]/2., submllength);
160 }
161 tempSLay1 = &( (*tempSLay)<<submlpos);
162 } else {
163 std::cout << " problem with shape of temporary trapezoid in LogVolName "
164 << logVolName << " thick,width,length " << submlthick
165 << " " << submlwidths << " " << submllength << std::endl;
166 }
167
168 if (foamthicknessup > foamthicknesslow) {
169 if (foamthicknessup*submlwidths*submllength > 0) {
170 if (cutoutFullLength[isub]) {
171 tempSFoamup = new GeoTrd(foamthicknessup/2., foamthicknessup/2.,
172 submlwidths, submlwidthl, submllength);
173 } else {
174 tempSFoamup = new GeoTrd(foamthicknessup/2., foamthicknessup/2.,
175 cutoutTubeLength[isub]/2., cutoutTubeLength[isub]/2.,
176 submllength);
177 }
178
179 tempSFoamup1 = &( (*tempSFoamup)<<submlpos);
180 } else {
181 std::cout << " problem with shape of upper foam trapezoid in LogVolName "
182 << logVolName << " thick,width,length " << foamthicknessup
183 << " " << submlwidths << " " << submllength << std::endl;
184 }
185 } else {
186 if (foamthicknesslow*submlwidths*submllength > 0) {
187 if (cutoutFullLength[isub]) {
188 tempSFoamlow = new GeoTrd(foamthicknesslow/2., foamthicknesslow/2.,
189 submlwidths, submlwidthl, submllength);
190 } else {
191 tempSFoamlow = new GeoTrd(foamthicknesslow/2., foamthicknesslow/2.,
192 cutoutTubeLength[isub]/2., cutoutTubeLength[isub]/2.,
193 submllength);
194 }
195 tempSFoamlow1 = &( (*tempSFoamlow)<<submlpos);
196 } else {
197 std::cout << " problem with shape of lower foam trapezoid in LogVolName "
198 << logVolName << " thick,width,length " << foamthicknesslow
199 << " " << submlwidths << " " << submllength << std::endl;
200 }
201 }
202
203 submlwidths = submlwidthl;
204
205 if (slay) {
206 if (verbose_multilayer) std::cout << " Layer " << slay << " in " << logVolName
207 << " exists - add step section to it " << std::endl;
208 slay = &(slay->add(*tempSLay1));
209 if (foamthicknessup > 0.) sfoamup = &(sfoamup->add(*tempSFoamup1));
210 if (foamthicknesslow > 0.) sfoamlow = &(sfoamlow->add(*tempSFoamlow1));
211
212 } else {
213 if (verbose_multilayer) std::cout << " Layer slay in " << logVolName
214 << " does not yet exist - create it " << std::endl;
215 slay = tempSLay1;
216 if (foamthicknessup > 0.) sfoamup = tempSFoamup1;
217 if (foamthicknesslow > 0.) sfoamlow = tempSFoamlow1;
218 }
219 }
220 }
221
222
223
224 const GeoShape* stube = NULL;
225 double tL = longWidth/2.0 - (tubePitch/2.)*TrdDwoverL;
226 stube = new GeoTube(0.0, tubePitch/2., tL);
227 stube = & ( (*stube) << HepRotateX3D(90.*deg) );
228 const GeoShape* stubewithcut = NULL;
229 if (cutoutNsteps > 1) {
230 double toptubelength = cutoutTubeLength[cutoutNsteps-1];
231 if (cutoutFullLength[cutoutNsteps-1]) toptubelength = longWidth;
232 stubewithcut = new GeoTube(0.0, tubePitch/2., toptubelength/2.0);
233 stubewithcut = & ( (*stubewithcut) << HepRotateX3D(90.*deg) );
234 }
235
236 GeoShape* sbox = new GeoTrd(mdtthickness, mdtthickness, longWidth,
237 longWidth, tubePitch/2.);
238 GeoShape* sboxf = new GeoTrd(mdtthickness, mdtthickness, longWidth,
239 longWidth, tubePitch/4.+1*mm);
240 slay = &(slay->subtract( (*sbox)<<HepTranslate3D(0.,0.,length/2.)));
241
242 for (int i = 0; i < nrOfLayers; i++) {
243 if (xx[i] > tubePitch/2. + 10.*mm) {
244
245 if (verbose_multilayer) std::cout << " Cutting tube at xx = " << yy[i]
246 << " z = " << -length/2. << std::endl;
247 slay = &(slay->subtract( (*stube)<<HepTranslate3D(-mdtthickness/2.+yy[i],0.,-length/2.) ));
248
249
250 if (cutoutNsteps == 1) {
251
252 if (verbose_multilayer) std::cout << " Adding tube at xx = " << yy[i]
253 << " z = " << length/2. << std::endl;
254 slay = &(slay->add( (*stube)<<HepTranslate3D(-mdtthickness/2.+yy[i],0.,length/2.-tubePitch/2.) ));
255 } else {
256
257 if (verbose_multilayer) std::cout << " Adding tube at xx = " << yy[i]
258 << " y(cutout!) = " << cutoutXtubes[cutoutNsteps-1]
259 << " z = " << length/2. << std::endl;
260 slay = &(slay->add( (*stubewithcut)
261 <<HepTranslate3D(-mdtthickness/2.+yy[i],
262 cutoutXtubes[cutoutNsteps-1],
263 length/2.-tubePitch/2.) ));
264 }
265 }
266 }
267
268 const GeoMaterial* mlay = matManager->getMaterial("std::Air");
269 GeoLogVol* llay = new GeoLogVol(logVolName, slay, mlay);
270 GeoFullPhysVol* play = new GeoFullPhysVol(llay);
271
272 double foamposition;
273 const GeoShape* sfoam = NULL;
274 const GeoMaterial* mfoam = NULL;
275 GeoLogVol* lfoam = NULL;
276 GeoPhysVol* pfoam = NULL;
277
278 if (foamthicknesslow != 0) {
279 foamposition = -(mdtthickness - foamthicknesslow)/2.;
280 if (sfoamlow) {
281 sfoam = sfoamlow;
282 } else {
283 sfoam = new GeoTrd(foamthicknesslow/2.-eps, foamthicknesslow/2.-eps,
284 width/2.-eps, longWidth/2.-eps, length/2.);
285 }
286 sfoam = &(sfoam->subtract( (*sboxf)<<HepTranslate3D(0.,0.,length/2.-tubePitch/4.)));
287 mfoam = matManager->getMaterial("muo::Foam");
288 lfoam = new GeoLogVol("MultiLayerFoam", sfoam, mfoam);
289
290 } else if (foamthicknessup != 0) {
291 foamposition = (mdtthickness - foamthicknessup)/2.;
292 if (sfoamup) {
293 sfoam = sfoamup;
294 } else {
295 sfoam = new GeoTrd(foamthicknessup/2.-eps, foamthicknessup/2.-eps,
296 width/2.-eps, longWidth/2.-eps, length/2.);
297 }
298 sfoam = &(sfoam->subtract( (*sboxf)<<HepTranslate3D(0.,0.,length/2.-tubePitch/4.)));
299 mfoam = matManager->getMaterial("muo::Foam");
300 lfoam = new GeoLogVol("MultiLayerFoam", sfoam, mfoam);
301
302 } else {
303 throw std::runtime_error("ATTENTION: no foam");
304 }
305
306 pfoam = new GeoPhysVol(lfoam);
307 GeoTransform* xf = new GeoTransform (HepTranslateX3D(foamposition));
308 GeoNameTag* nt = new GeoNameTag(name+" MultiLayerFoam");
309 play->add(new GeoIdentifierTag(0));
310 play->add(nt);
311 play->add(xf);
312 play->add(pfoam);
313
314
315
316 double diff = (longWidth - width)*(length - tubePitch/2.)/length;
317 int nrTubesPerStep = nrOfTubes/nrOfSteps;
318 std::vector<GeoVPhysVol*> tubeVector;
319 std::vector<bool> internalCutout;
320 std::vector<double> tubeDX;
321 std::vector<double> tubeL;
322 std::vector<int> Ntubes;
323
324
325 if (cutoutNsteps <= 1) {
326 for (int j = 0; j < nrOfSteps; j++) {
327 tube.length=width+j*diff/nrOfSteps;
328
329 if (verbose_multilayer)std::cout<<" logVolName "<<logVolName<<" step = "<<j
330 <<" tube length = "<<tube.length<<std::endl;
331 tubeVector.push_back(tube.build());
332 }
333
334
335 } else {
336 if (verbose_multilayer)std::cout<<" logVolName "<<logVolName
337 <<" cutoutNsteps ="<< cutoutNsteps
338 <<" nsteps "<<nrOfSteps<<std::endl;
339 int ntubes = 0;
340
341
342
343 for (int j = 0; j < nrOfSteps; j++) {
344 if (verbose_multilayer) std::cout << " Building tube vectors for step " << j << std::endl;
345 double tlength = width + j*diff/nrOfSteps;
346 double tlen = 0.;
347 double previousTlen = -1.;
348 int nTubeToSwitch[5];
349 for (int ii = 0; ii < cutoutNsteps; ii++) {
350 if (verbose_multilayer) std::cout << " Building tube vectors for cutout step " << ii << std::endl;
351 nTubeToSwitch[ii] = cutoutNtubes[ii] - 1;
352 if (ii > 0) {
353 for (int k = ii-1; k >= 0; k--) {
354 nTubeToSwitch[ii] += cutoutNtubes[k];
355 }
356 }
357 if (verbose_multilayer) std::cout<<" nTubeToSwitch["<<ii<<"]="<<nTubeToSwitch[ii]<<std::endl;
358 }
359
360
361 for (int it = 0; it < nrTubesPerStep; it++) {
362 tlen = tlength;
363 double dx = 0.;
364
365
366 int weAreInCutStep=0;
367 for (int ic = 0; ic < cutoutNsteps; ic++) {
368 if (verbose_multilayer) std::cout << " Loop over cuts ic " << ic
369 << " FullLength " << cutoutFullLength[ic]
370 << " ymax " << cutoutYmax[ic] << std::endl;
371 if (it + nrTubesPerStep*j > nTubeToSwitch[ic]) weAreInCutStep++;
372 }
373
374 if (verbose_multilayer) std::cout << " Tube " << it << " is in cut step "
375 << weAreInCutStep << std::endl;
376
377
378 if (nrOfSteps == 1 || !cutoutFullLength[weAreInCutStep]) {
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393 tlen = cutoutTubeLength[weAreInCutStep];
394 dx = cutoutXtubes[weAreInCutStep];
395 if (longWidth > width) tlen -= 3;
396
397
398
399
400
401
402
403
404
405 }
406 if (std::abs(tlen-previousTlen) > 0.001) {
407 tube.length=tlen;
408 tubeVector.push_back(tube.build());
409 if (weAreInCutStep < 1) {
410 internalCutout.push_back(false);
411 } else {
412 internalCutout.push_back(!cutoutFullLength[weAreInCutStep] &&
413 cutoutYmax[weAreInCutStep] < length - tubePitch/2.);
414 }
415 tubeDX.push_back(dx);
416 tubeL.push_back(tlen);
417 previousTlen = tlen;
418 if (ntubes > 0) Ntubes.push_back(ntubes);
419 ntubes = 1;
420
421 } else {
422 ntubes++;
423 }
424
425 if ((j*nrOfSteps + it) == nrOfTubes - 1) Ntubes.push_back(ntubes);
426 if (verbose_multilayer) std::cout << " ntubes = " << ntubes << std::endl;
427 }
428 }
429 }
430
431
432
433 double lstart;
434 double tstart;
435 GeoSerialDenominator* sd = new GeoSerialDenominator("DriftTube");
436 play->add(sd);
437 if (cutoutNsteps > 1) {
438
439 for (int i = 0; i < nrOfLayers; i++) {
440 tstart = -mdtthickness/2. + yy[i];
441 int extraTube = 0;
442 if (xx[i] < tubePitch - 1.0) extraTube = 1;
443 double loffset = 0.;
444 int nttot = 0;
445 bool nextTimeSubtract = false;
446 for (unsigned int j = 0; j < tubeVector.size(); j++) {
447 GeoVPhysVol* tV = tubeVector[j];
448 double dy = tubeDX[j];
449 int nt = Ntubes[j];
450
451 if (nextTimeSubtract) {
452 nt -= extraTube;
453 nextTimeSubtract = false;
454 }
455 if (internalCutout[j]) {
456 nt += extraTube;
457 nextTimeSubtract = true;
458 }
459 if (nt > 0) {
460 loffset = nttot*tubePitch;
461 lstart = loffset - length/2. + xx[i];
462 Genfun::Variable K;
463 Genfun::GENFUNCTION f = tubePitch*K + lstart;
464 TRANSFUNCTION t = HepTranslateY3D(dy)*HepRotateX3D(90*deg)*
465 HepTranslateX3D(tstart)*Pow(HepTranslateY3D(1.0),f);
466 GeoSerialTransformer* s = new GeoSerialTransformer(tV,&t,nt);
467 play->add(new GeoSerialIdentifier(100*(i+1)+nttot + 1));
468 play->add(s);
469
470 nttot = nttot + nt;
471 if (verbose_multilayer)
472 std::cout << " placing " << nt << " tubes of length " << tubeL[j]
473 << " starting at t = " << tstart << " , y = " << lstart
474 << " and x = " << dy << " with " << nttot
475 << " tubes so far " << std::endl;
476 }
477 }
478 }
479
480 } else if (nrOfSteps == 1) {
481
482 for (int i = 0; i < nrOfLayers; i++) {
483 tstart = -mdtthickness/2. + yy[i];
484 lstart = -length/2. + xx[i];
485
486
487 Genfun::Variable K;
488 Genfun::GENFUNCTION f = tubePitch*K + lstart;
489 TRANSFUNCTION t = HepRotateX3D(90*deg)*HepTranslateX3D(tstart)*
490 Pow(HepTranslateY3D(1.0),f);
491 GeoVPhysVol* tV = tubeVector[0];
492 GeoSerialTransformer* s = new GeoSerialTransformer(tV,&t,nrOfTubes);
493 play->add(new GeoSerialIdentifier(100*(i+1)+1));
494 play->add(s);
495 }
496 } else {
497
498 lstart = 0.;
499 for (int i = 0; i < nrOfLayers; i++) {
500 tstart = -mdtthickness/2. + yy[i];
501 double loffset = 0.;
502 for (int j = 0; j < nrOfSteps; j++) {
503 GeoVPhysVol* tV = tubeVector[j];
504 loffset = j*nrTubesPerStep*tubePitch;
505 lstart = loffset - length/2. + xx[i];
506 Genfun::Variable K;
507 Genfun::GENFUNCTION f = tubePitch*K + lstart;
508 TRANSFUNCTION t = HepRotateX3D(90*deg)*HepTranslateX3D(tstart)*
509 Pow(HepTranslateY3D(1.0),f);
510 GeoSerialTransformer* s = new GeoSerialTransformer(tV,&t,nrTubesPerStep);
511 play->add(new GeoSerialIdentifier(100*(i+1)+j*nrTubesPerStep + 1));
512 play->add(s);
513 }
514 }
515 }
516
517 return play;
518 }
519
520
521 void MultiLayer::print()
522 {
523 std::cout << "Multi Layer " << name.c_str() << " :" << std::endl;
524
525 }
526 }
527
| Due to the LXR bug, the updates fail sometimes to remove references to deleted files. The Saturday's full rebuilds fix these problems |
|
This page was automatically generated by the
LXR engine.
|
|