#include #include #include #include #include #include #include "DWUnits.hh" #include "preXmlManager.hh" #include "preXmlInteger.hh" #include "preXmlAngle.hh" #include "preXmlLength.hh" #include "preXmlNumber.hh" #include "agddSection.hh" #include "agddBox.hh" #include "agddTrd.hh" #include "agddTubs.hh" #include "agddCons.hh" #include "agddCompos.hh" #include "agddUnion.hh" #include "agddSubtraction.hh" #include "agddMPosPhi.hh" #include "agddPosXYZ.hh" #include "agddAGDD.hh" #include "agddNumberString.hh" #include "agddUserGeometry.hh" typedef agdd::UserGeometry::OutputStructure OutputStruct; OutputStruct agdd::UserGeometry::defineUserGeometry() { preXml::Manager & useMy = *(_in.preXmlManager); agdd::UserGeometry::OutputStructure outStruct; // At the top of the preXml file, the dtd insists on the existence // of at least one "geometry" (and possibly more, nested if necessary). // The "geometries" are very much like directories. They permit // the user to store more than one description of the detector in // one preXml file. // // So, before we can proceed, we must tell the preXml::Manager which // of these "geometries" (there may of course only be one!) we wish // to build the output-XML-file from. // This we do in the same was as "changing directories" on a file- // system. When we get to the geometry we want, we tell the // preXml::Manager to setGeometry(), and that's all there is to it. // Here we choose the geometry to work on. useMy.geoManager().changeDir(string("G4WorkGeometry")); useMy.setGeometry(); // Now that we've chosen the geometry, we have restricted ourselves // to a part of the preXml file that describes just one detector. // // If we were confident enough (I'm not!) that nobody working on // a different sub-detector to us had created a name-clash for us, // then we could go right ahead and start reading data from the // preXml file immediately. // If we were to follow this "go right ahead" method, the // preXml::Manager would spot any name clashes and tell us about them, // so nothing would go wrong. However, having to fixing the clash // would still involve finding the person from the other sub-detector // responsible for the clash, etc, etc, etc. This could take time. // // A much better solution is for us to use the structure of the // "sections" (again used just like directories) which each geometry // in the preXml file is broken down into. // If I "change directory" to the section that is my sole // responsibility, then if there is any problem, I only have to // grumble to myself. Since I'm working on the SCT barrel, // I'll go there: assert(useMy.secManager().changeDir(string("ATLAS"))); assert(useMy.secManager().changeDir(string("InnerDetector"))); // I asserted these just to check that I succeeded. // Now we start the geometry proper. // Let's define a section agdd::Section * barrelSection=new agdd::Section; // Here are the section's parameters: barrelSection->setName("sct_barrel_section"); barrelSection->setVersion("preliminary version of current geometry"); barrelSection->setAuthor("Christopher Lester"); // Better make a "top_volume". agdd::Compos * barrelCompos = new agdd::Compos(); barrelCompos->setName("sct_barrel"); barrelSection->setTopVol(barrelCompos); agdd::AGDD * theAGDD=new agdd::AGDD; theAGDD->addSection(barrelSection); outStruct.theBuildable=theAGDD; {{ // This is where the old SCT.geo.hh started // We're going to read those parameters which interest // us from the preXml file, and then produce the // relevant output. // The xml file comes to us as the element called doc. // Since there are potential name clashes everywhere, let's // restrict ourselves to looking in only that part of the preXml file // which is relevant to the SCT barrel and this particular geometry. // Some macros follow which save a bit of typing. // All they do is read values from the preXml file // and store them in constants and const vectors. // They make use of the fact that I have the same // names for my variables both in this program AND // in the preXml file. You don't have to do it // this way if you don't want to. By way of example, // I've typed the first "read" in it's expanded form. #define MYSET(t,v) \ preXml:: t v ; \ useMy.fill( v , #v ); \ cout << "I found "<< #v <<" = "<< v << endl; #define MYSETARRAY(t,v,n) \ vector< preXml:: t > v ( n ) ; \ useMy.fill( v , #v ) ; \ { \ for(int i=0; i< n ;i++) { \ cout << "I found "<< #v <<"["<setBox(doubleWaferLength, doubleWaferWidth, doubleWaferThickness); doubleWafer->setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(doubleWafer); // and here is the moduleSensitive (ie two back to back wafers) agdd::Compos * barrelModuleSensitive = new agdd::Compos; assert(barrelModuleSensitive); barrelModuleSensitive->setName("sct_barrelModuleSensitive"); // into which we put the following: //HGFHGFbarrelSection.addVolume(barrelModuleSensitive); { agdd::PosXYZ * outerPos = new agdd::PosXYZ; agdd::PosXYZ * innerPos = new agdd::PosXYZ; outerPos->setVolume(doubleWafer); innerPos->setVolume(doubleWafer); outerPos->setRot(0.0, 0.0, barrelStereoOuter); innerPos->setRot(0.0, 0.0, barrelStereoInner); const double shift = 0.5*baseboardThickness + mountingSep + 0.5*doubleWaferThickness; outerPos->setXYZ(0.0, 0.0, +shift); innerPos->setXYZ(0.0, 0.0, -shift); barrelModuleSensitive->addPos(outerPos); barrelModuleSensitive->addPos(innerPos); } /* // Here is a Wafer. agdd::Box & wafer = barrelSection.adopt(new agdd::Box()); wafer.setName("sct_wafer"); wafer.setBox(waferThickness, waferWidth, waferLength); wafer.setMaterial("cheese"); FFFFFFbarrelSection.addVolume(wafer); // Here is a DoubleWafer. agdd::PosXYZ & topWafer = barrelSection.adopt(new agdd::PosXYZ()); agdd::PosXYZ & botWafer = barrelSection.adopt(new agdd::PosXYZ()); topWafer.setVolume(wafer); botWafer.setVolume(wafer); topWafer.setXYZ(0., 0., +(waferLength+waferSep)/2.0); botWafer.setXYZ(0., 0., -(waferLength+waferSep)/2.0); agdd::Compos & doubleWafer = barrelSection.adopt(new agdd::Compos()); doubleWafer.setName("sct_doubleWafer"); doubleWafer.addPos(topWafer); doubleWafer.addPos(botWafer); FFFFFFbarrelSection.addVolume(doubleWafer); */ // Here is facingCooledUpper: // the lack of a "facing shaped solid" means that this is only approximate. // Currently, positioning also involves some guesswork. // I will try to keep the axis at the (inner) (right angled) corner // nearest the physics centre. // This must be corrected at some point LESTER. // facingCooledUpper agdd::Union * facingCooledUpper = new agdd::Union(); agdd::Union * facingCooledLower = new agdd::Union(); { for (int i=0; i<2; i++) { agdd::Union * facPtr=0; bool isUpper; if (i==0) { // upper isUpper=true; facPtr = facingCooledUpper; } else { // lower isUpper=false; facPtr = facingCooledLower; } //HGFHGFbarrelSection.addVolume(facPtr); facPtr->setName(isUpper? "sct_facingCooledUpper": "sct_facingCooledLower"); facPtr->setMaterial("swissCheese"); { // Here comes a fiddle, since general quadrilateral is not an option. { agdd::Box * sol = new agdd::Box; //HGFHGFbarrelSection.addVolume(sol); sol->setName(isUpper? "sct_facingCooledUpperPart1": "sct_facingCooledLowerPart1"); //sol->setMaterial("cheese"); const double wA = isUpper? facingCooledUpperWidthA: facingCooledLowerWidthA; const double wB = isUpper? facingCooledUpperWidthB: facingCooledLowerWidthB; const double minWidth = min(wA,wB); const double solx = isUpper? facingCooledUpperLength: facingCooledLowerLength; const double soly = minWidth; const double solz = facingThickness; sol->setBox(solx, soly, solz); { agdd::PosXYZ * pos = new agdd::PosXYZ; pos->setVolume(sol); pos->setXYZ(+0.5*solx, +0.5*soly, (isUpper?+0.5:-0.5)*solz); facPtr->addSolidPos(pos); } { agdd::Trd * sol = new agdd::Trd(); //HGFHGFbarrelSection.addVolume(sol); sol->setName(isUpper? "sct_facingCooledUpperPart2": "sct_facingCooledLowerPart2"); sol->setMaterial("cheese"); const double ang = isUpper? barrelStereoOuter: barrelStereoInner; const double xWidth = facingThickness; const double yWidth = 2.0*solx*sin(0.5*abs(ang/DWradian)); const double zLen = 1.0*solx*cos(0.5*abs(ang/DWradian)); // will construct this balancing on pointy end sol->setTrd(xWidth, xWidth, 0.001*DWmm, // Fixes bug in persint. yWidth, zLen); { agdd::Union * sideTrd=new agdd::Union; //HGFHGFbarrelSection.addVolume(sideTrd); sideTrd->setName(isUpper? "sct_cooledFacingUpperSideTrd": "sct_cooledFacingLowerSideTrd"); agdd::PosXYZ * pos = new agdd::PosXYZ; pos->setVolume(sol); const double rotAng=(ang>0)?+90.0*DWdegree:-90.0*DWdegree; pos->setRot(0.0, rotAng, 0.0); // Now the triangle is on its side, held by the // lower part of of its tip. sideTrd->addSolidPos(pos); { agdd::PosXYZ * pos = new agdd::PosXYZ; pos->setVolume(sideTrd); pos->setRot(0.0, 0.0, 0.5*ang); const double aOver2=abs(0.5*ang); pos->setXYZ(+1.0*solx-solx/(2.0*cos(aOver2/DWradian)), +1.0*soly+0.5*solx*sin(aOver2/DWradian), (isUpper?+0.5:-0.5)*facingThickness); facPtr->addSolidPos(pos); } } } } } } } // Here is a baseboard. agdd::Volume * baseboardPtr = 0; if (moduleFaithfulness>=0) { // Can develop this a little if desired. #define UNION #ifdef NIBBLE /* { // NIBBLE METHOD // here is the uncut base agdd::Box & baseboardStart = barrelSection.adopt(new agdd::Box(barrelSection)); baseboardStart.setName("sct_baseboardUncut"); baseboardStart.setBox(baseboardLength, baseboardWidth, baseboardThickness); //baseboardStart.setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(baseboardStart); agdd::PosXYZ & baseboardStartPos = barrelSection.adopt(new agdd::PosXYZ); baseboardStartPos.setVolume(baseboardStart); // here are the nibbles agdd::Box & baseboardChunkTLLarge = barrelSection.adopt(new agdd::Box(barrelSection)); agdd::Box & baseboardChunkTLSmall = barrelSection.adopt(new agdd::Box(barrelSection)); agdd::Box & baseboardChunkTR = barrelSection.adopt(new agdd::Box(barrelSection)); agdd::Box & baseboardChunkBL = barrelSection.adopt(new agdd::Box(barrelSection)); baseboardChunkTLLarge.setName("sct_baseboardTLLargeNibble"); baseboardChunkTLSmall.setName("sct_baseboardTLSmallNibble"); baseboardChunkTR .setName("sct_baseboardTRNibble"); baseboardChunkBL .setName("sct_baseboardBLNibble"); baseboardChunkTLLarge.setBox(chunkTLLarge[0], chunkTLLarge[1], baseboardThickness); baseboardChunkTLSmall.setBox(chunkTLSmall[0], chunkTLSmall[1], baseboardThickness); baseboardChunkTR .setBox(chunkTR [0], chunkTR [1], baseboardThickness); baseboardChunkBL .setBox(chunkBL [0], chunkBL [1], baseboardThickness); //baseboardChunkTLLarge.setMaterial("cheese"); //baseboardChunkTLSmall.setMaterial("cheese"); //baseboardChunkTR .setMaterial("cheese"); //baseboardChunkBL .setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(baseboardChunkTLLarge); //HGFHGFbarrelSection.addVolume(baseboardChunkTLSmall); //HGFHGFbarrelSection.addVolume(baseboardChunkTR ); //HGFHGFbarrelSection.addVolume(baseboardChunkBL ); agdd::PosXYZ & baseboardTLLargePos = barrelSection.adopt(new agdd::PosXYZ); agdd::PosXYZ & baseboardTLSmallPos = barrelSection.adopt(new agdd::PosXYZ); agdd::PosXYZ & baseboardTRPos = barrelSection.adopt(new agdd::PosXYZ); agdd::PosXYZ & baseboardBLPos = barrelSection.adopt(new agdd::PosXYZ); baseboardTLLargePos.setVolume(baseboardChunkTLLarge); baseboardTLSmallPos.setVolume(baseboardChunkTLSmall); baseboardTRPos .setVolume(baseboardChunkTR ); baseboardBLPos .setVolume(baseboardChunkBL ); // The following distances (start board edges to physics origin) // will shortly come in handy. const double left = baseboardOriginX; const double bottom = baseboardOriginY; const double right = baseboardLength-baseboardOriginX; const double top = baseboardWidth -baseboardOriginY; // carry on // now locate the base and nibbles relative to the physics origin: baseboardStartPos .setXYZ(+0.5*baseboardLength-baseboardOriginX, +0.5*baseboardWidth -baseboardOriginY, 0.0); baseboardTLLargePos.setXYZ(-left + 0.5*chunkTLLarge[0], +top - 0.5*chunkTLLarge[1], 0.0); baseboardTLSmallPos.setXYZ(-left + 0.5*chunkTLSmall[0], +top - 0.5*chunkTLSmall[1], 0.0); baseboardTRPos .setXYZ(+right - 0.5*chunkTR[0], +top - 0.5*chunkTR[1], 0.0); baseboardBLPos .setXYZ(-left + 0.5*chunkBL[0], -bottom + 0.5*chunkBL[1], 0.0); // now form the subtraction itself. agdd::Subtraction * subPtr = new agdd::Subtraction(barrelSection); agdd::Subtraction & baseboard = barrelSection.adopt(subPtr); baseboardPtr=subPtr; subPrt->setMaterial("cheeseForNibbledBaseboard"); baseboard.addPos(baseboardStartPos); baseboard.addPos(baseboardTLLargePos); baseboard.addPos(baseboardTLSmallPos); baseboard.addPos(baseboardTRPos); baseboard.addPos(baseboardBLPos); baseboard.setName("sct_barrelModuleBaseboard"); //HGFHGFbarrelSection.addVolume(baseboardPtr); } */ #endif #ifdef UNION { // the Union method agdd::Union * uniPtr = new agdd::Union; agdd::Union * baseboard = uniPtr; baseboardPtr=uniPtr; baseboard->setMaterial("swissCheeseForBase"); //HGFHGFbarrelSection.addVolume(baseboard); baseboard->setName("sct_barrelModuleBaseboard"); const int blocks=5; const double lGap[blocks] = {chunkBL[0], chunkBL[0], 0.0, chunkTLLarge[0], chunkTLSmall[0]}; const double rGap[blocks] = {0.0, chunkTR[0], chunkTR[0], chunkTR[0], chunkTR[0]}; const double tops[blocks] = {baseboardWidth-chunkTR[1], chunkBL[1], baseboardWidth-chunkTLLarge[1], baseboardWidth-chunkTLSmall[1], baseboardWidth}; double lastTop=0; for (int block=0; blocksetName(tmp.str()); } const double bLen = baseboardLength - lGap[block] - rGap[block]; const double bWid = tops[block]-lastTop; b->setBox(bLen, bWid, baseboardThickness); //b->setMaterial("cheese"); // now that the block is defined, position it { agdd::PosXYZ * p = new agdd::PosXYZ; p->setVolume(b); p->setXYZ(0.5*bLen + lGap[block] - baseboardOriginX, 0.5*bWid + lastTop - baseboardOriginY, 0.0); cout << "***" <<0.5*bWid << " " << lastTop << " " << baseboardOriginY << " " << 0.5*bWid + lastTop - baseboardOriginY << endl; baseboard->addSolidPos(p); } // lastly prepare lastTop for the next loop lastTop=tops[block]; } } #endif } // here ends the baseboard. // put baseboard and facings together. agdd::Compos * fAndB = new agdd::Compos; //HGFHGFbarrelSection.addVolume(fAndB); fAndB->setName("sct_baseboardAssembly"); { { // baseboard itself agdd::PosXYZ * b = new agdd::PosXYZ; b->setVolume(baseboardPtr); fAndB->addPos(b); } { // cooled upper facing agdd::PosXYZ * cU = new agdd::PosXYZ; cU->setVolume(facingCooledUpper); cU->setXYZ(-baseboardOriginX+chunkBL[0], -baseboardOriginY, +0.5*baseboardThickness+adhesiveSep); fAndB->addPos(cU); } { // cooled lower facing agdd::PosXYZ * cL = new agdd::PosXYZ; cL->setVolume(facingCooledLower); cL->setXYZ(-baseboardOriginX+chunkBL[0], -baseboardOriginY, -0.5*baseboardThickness-adhesiveSep); fAndB->addPos(cL); } } // Here is a hybrid. // The total hybrid, when complete, has is origin here: // level with the soles of its feet, and at a distance // 'hybridOffset' directly away from the middle of the // hybrid edge nearest the physics centre. // LESTER Would the following as a UNION be better? agdd::Compos * outerHybrid = new agdd::Compos; outerHybrid->setName("sct_outerBarrelHybrid"); //HGFHGFbarrelSection.addVolume(outerHybrid); // Now I fill up the hybrid with its various components. { // slivers agdd::Box * sliver = new agdd::Box; //HGFHGFbarrelSection.addVolume(sliver); sliver->setName("sct_outerHybridSliver"); sliver->setMaterial("cheese"); const double sliverThickness=hybridThicknessAtStep-hybridThicknessAtCentre; sliver->setBox(hybridWidth, hybridStepWidth, sliverThickness); agdd::PosXYZ * topSliver = new agdd::PosXYZ; agdd::PosXYZ * botSliver = new agdd::PosXYZ; topSliver->setVolume(sliver); // most distant from cooling botSliver->setVolume(sliver); // nearest cooling topSliver->setXYZ( 0.5*hybridWidth+hybridOffset, +0.5*hybridLength-0.5*hybridStepWidth, 0.5*sliverThickness); botSliver->setXYZ( 0.5*hybridWidth+hybridOffset, -0.5*hybridLength+0.5*hybridStepWidth, 0.5*sliverThickness); outerHybrid->addPos(topSliver); outerHybrid->addPos(botSliver); // bridge agdd::Box * bridge = new agdd::Box; //HGFHGFbarrelSection.addVolume(bridge); bridge->setName("sct_outerHybridBridge"); bridge->setMaterial("cheese"); const double bridgeThickness=hybridThicknessAtCentre; bridge->setBox(hybridWidth, hybridLength, bridgeThickness); agdd::PosXYZ * bridgePos = new agdd::PosXYZ; bridgePos->setVolume(bridge); bridgePos->setXYZ(0.5*hybridWidth+hybridOffset, 0.0, sliverThickness+0.5*bridgeThickness); outerHybrid->addPos(bridgePos); } agdd::Compos * innerHybrid = new agdd::Compos; //HGFHGFbarrelSection.addVolume(innerHybrid); innerHybrid->setName("sct_innerBarrelHybrid"); { agdd::PosXYZ * pos = new agdd::PosXYZ; pos->setVolume(outerHybrid); pos->setRot(180.0*DWdegree, 0.0, 0.0); innerHybrid->addPos(pos); } /* // Here is an ElectronicsBoard agdd::Box & electronicsBoard = barrelSection.adopt(new agdd::Box()); electronicsBoard.setName("sct_electronicsBoard"); electronicsBoard.setBox(tckEle, boardWidth, elecZ); electronicsBoard.setMaterial("cheese"); FFFFFFbarrelSection.addVolume(electronicsBoard); // Here is a SECT agdd::PosXYZ & waferPos = barrelSection.adopt(new agdd::PosXYZ()); agdd::PosXYZ & boardPos = barrelSection.adopt(new agdd::PosXYZ()); waferPos.setVolume(doubleWafer); //boardPos.setVolume(electronicsBoard); boardPos.setXYZ(0., -(waferWidth+boardWidth)/2.0, 0.); agdd::Compos & sect = barrelSection.adopt(new agdd::Compos()); sect.setName("sct_sect"); sect.addPos(waferPos); sect.addPos(boardPos); FFFFFFbarrelSection.addVolume(sect); */ // Here is a barrelModule agdd::Compos * barrelModule = new agdd::Compos; //HGFHGFbarrelSection.addVolume(barrelModule); barrelModule->setName("sct_barrelModule"); // Now we position things inside the module: { { // first the sensitive stuff agdd::PosXYZ * sensPos = new agdd::PosXYZ; sensPos->setVolume(barrelModuleSensitive); barrelModule->addPos(sensPos); } { // now the baseboard agdd::PosXYZ * basePos = new agdd::PosXYZ; basePos->setVolume(fAndB); barrelModule->addPos(basePos); } { // now the hybrids agdd::PosXYZ * outerPos = new agdd::PosXYZ; agdd::PosXYZ * innerPos = new agdd::PosXYZ; outerPos->setVolume(outerHybrid); innerPos->setVolume(innerHybrid); outerPos->setXYZ(0.0, 0.0, +0.5*baseboardThickness+facingThickness+2.0*adhesiveSep); innerPos->setXYZ(0.0, 0.0, -0.5*baseboardThickness-facingThickness-2.0*adhesiveSep); outerPos->setRot(0.0, 0.0, barrelStereoOuter); innerPos->setRot(0.0, 0.0, barrelStereoInner); barrelModule->addPos(outerPos); barrelModule->addPos(innerPos); } } // Here is an SLMP. // NOTE: // This implementation fixes a bug in the old G3 // definition which read something like: // df << DeeDoubleUBox(tckLum, wdthLum, hLen*2.); // which caused the lump volume to overlap the // insulation volume. // I substitute this instead. agdd::Box * slmp = new agdd::Box; slmp->setName("sct_slmp"); slmp->setBox(tckLum, wdthLum, zCylEnd*2.); slmp->setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(slmp); // Here is a SCAB which is a representation of cabling. agdd::Cons * scab = new agdd::Cons; scab->setName("sct_scab"); scab->setCons(inn1,out1, inn2,out2, zCylEnd); scab->setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(scab); // Here is a DoubleSCAB agdd::PosXYZ * posPos = new agdd::PosXYZ; agdd::PosXYZ * negPos = new agdd::PosXYZ; posPos->setVolume(scab); negPos->setVolume(scab); posPos->setXYZ(0., 0., +zCylEnd/2.); negPos->setXYZ(0., 0., -zCylEnd/2.); posPos->setRot(0., 0.*DWdegree, 0.); negPos->setRot(0., 180.*DWdegree, 0.); agdd::Compos * doubleScab = new agdd::Compos; doubleScab->setName("sct_doubleScab"); doubleScab->addPos(posPos); doubleScab->addPos(negPos); //HGFHGFbarrelSection.addVolume(doubleScab); // Here are nLay Flanges vector flange; { for (int i=0; isetName(o.str()); flange[i]->setTubs(r0Sup[i]-flLen[i], r0Sup[i], tckFl[i]); flange[i]->setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(flange[i]); } } // Here are nLay CloseOuts vector closeOut; { for (int i=0; isetName(o.str()); closeOut[i]->setTubs(r0Sup[i]-tckClo[i], r0Sup[i], cOLen[i]); closeOut[i]->setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(closeOut[i]); } } // Here are nLay Supports vector support; { for (int i=0; isetName(o.str()); support[i]->setTubs(r0Sup[i]-tckSup[i],r0Sup[i],2.*(zCylEnd-cOLen[i]-tckFl[i])); support[i]->setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(support[i]); } } // Here is the InsulationEnd agdd::Tubs * insulationEnd = new agdd::Tubs; insulationEnd->setName("sct_insulationEnd"); insulationEnd->setTubs(rMin, rMax, tckIso); insulationEnd->setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(insulationEnd); // Here is the InsulationCyl agdd::Tubs * insulationCyl = new agdd::Tubs; insulationCyl->setName("sct_insulationCyl"); insulationCyl->setTubs(rMax-tckIso, rMax, 2.*zCylEnd); insulationCyl->setMaterial("cheese"); //HGFHGFbarrelSection.addVolume(insulationCyl); /* // Here is are two BarrelModules, Type1 and Type2 (Positive/negative stereo) agdd::PosXYZ & posInnerSectPos = barrelSection.adopt(new agdd::PosXYZ()); agdd::PosXYZ & negInnerSectPos = barrelSection.adopt(new agdd::PosXYZ()); agdd::PosXYZ & OuterSectPos1 = barrelSection.adopt(new agdd::PosXYZ()); agdd::PosXYZ & OuterSectPos2 = barrelSection.adopt(new agdd::PosXYZ()); posInnerSectPos.setVolume(sect); negInnerSectPos.setVolume(sect); OuterSectPos1.setVolume(sect); OuterSectPos2.setVolume(sect); posInnerSectPos.setXYZ(-(sectThickness+sectGap)/2., 0., 0.); negInnerSectPos.setXYZ(-(sectThickness+sectGap)/2., 0., 0.); OuterSectPos1.setXYZ(+(sectThickness+sectGap)/2., 0., 0.); OuterSectPos2.setXYZ(+(sectThickness+sectGap)/2., 0., 0.); posInnerSectPos.setRot(+stereoInner/DWdegree, 0., 0.); // LESTER Check sign negInnerSectPos.setRot(-stereoInner/DWdegree, 0., 0.); // LESTER Check sign agdd::Compos & posModule = barrelSection.adopt(new agdd::Compos()); agdd::Compos & negModule = barrelSection.adopt(new agdd::Compos()); posModule.setName("sct_posBarrelModule"); negModule.setName("sct_negBarrelModule"); posModule.addPos(posInnerSectPos); negModule.addPos(negInnerSectPos); posModule.addPos( OuterSectPos1); negModule.addPos( OuterSectPos2); FFFFFFbarrelSection.addVolume(posModule); FFFFFFbarrelSection.addVolume(negModule); // That's the end of the barrel modules. */ /* // Here are the nLay types of ski. vector ski; { for (int i=0; isetName(o.str()); int sn; // Will oscillate with the radial staggering. int j; // Module number for ((sn=-1, j=0); jaddPos(modulePos); } FFFFFFbarrelSection.addVolume(ski[i]); } } // There end all the skis. */ { // Here comes the Barrel. (This is a long one.) int i; // Loop variable to represent the layer. int sn; // Dummy variable indicating skiType. // First will position entities which // there are "one of" per layer. // Here starts the loop over the layers in the barrel. for ((sn=1,i=0); i=0); const double rad1 = sqrt(temp1)-max(tckLum, 2.*out2); const double rCab = rad1 + out2; const double yCab = max(wdthLum/2., rCab*tan((angle/4.)/DWradian)); */ // const double wactrot = sectLength*sin(stRA/DWradian)+waferWidth*cos(stRA/DWradian); // const double delX = layerRadius[i]+(-dXSki*cos(tilt/DWradian)+(wactrot/2.)*sin(tilt/DWradian)); // const double delY = (+dXSki*sin(tilt/DWradian)+(wactrot/2.)*cos(tilt/DWradian)); // const double alpha = angle/2.-atan(delY/delX)*DWradian; // const double rLump = rad1 + tckLum/2.; // OK. That's all the variables we need to define. // Let's get going with the placements. // First we make a composition for the layer: agdd::Compos * layer = new agdd::Compos; layer->setName("sct_layer"+makeNumberString(i+1)); //HGFHGFbarrelSection.addVolume(layer); // and then we place it in the barrel: agdd::PosXYZ * layerPos = new agdd::PosXYZ; layerPos->setVolume(layer); barrelCompos->addPos(layerPos); // Position the Lump and Cables /* agdd::MPosPhi & slmpPos = barrelSection.adopt(new agdd::MPosPhi); slmpPos.setVolume(slmp); slmpPos.setN(skisPerLayer[i]); slmpPos.setRZ(rLump, 0.); layer.addPos(slmpPos); */ /* agdd::MPosPhi & doubleScabPos = barrelSection.adopt(new agdd::MPosPhi); doubleScabPos.setVolume(doubleScab); doubleScabPos.setN(skisPerLayer[i]); doubleScabPos.setRZ(sqrt(rCab*rCab+yCab*yCab), 0.); doubleScabPos.setPhi0(atan(yCab/rCab)*DWradian); //LESTER Check sign layer.addPos(doubleScabPos); */ // That's finished positioning the cables. /* // Here come the skis. agdd::MPosPhi & skiPos = barrelSection.adopt(new agdd::MPosPhi); skiPos.setVolume(ski[i]); skiPos.setN(skisPerLayer[i]); skiPos.setRZ(layerRadius[i], 0.); skiPos.setRot(0., 0., -tiltOfLayer[i]); //LESTER Check sign skiPos.setPhi0(alpha+angle); layer.addPos(skiPos); // That completes the skis. */ // Position the CloseOuts, flanges and Supports agdd::PosXYZ * posCloseOutPos = new agdd::PosXYZ; agdd::PosXYZ * negCloseOutPos = new agdd::PosXYZ; posCloseOutPos->setVolume(closeOut[i]); negCloseOutPos->setVolume(closeOut[i]); posCloseOutPos->setXYZ(0., 0., +(zCylEnd-tckFl[i]-cOLen[i]/2.)); negCloseOutPos->setXYZ(0., 0., -(zCylEnd-tckFl[i]-cOLen[i]/2.)); layer->addPos(posCloseOutPos); layer->addPos(negCloseOutPos); agdd::PosXYZ * posFlangePos = new agdd::PosXYZ; agdd::PosXYZ * negFlangePos = new agdd::PosXYZ; posFlangePos->setVolume(flange[i]); negFlangePos->setVolume(flange[i]); posFlangePos->setXYZ(0., 0., +(zCylEnd-tckFl[i]/2.)); negFlangePos->setXYZ(0., 0., -(zCylEnd-tckFl[i]/2.)); layer->addPos(posFlangePos); layer->addPos(negFlangePos); agdd::PosXYZ * supportPos = new agdd::PosXYZ; supportPos->setVolume(support[i]); layer->addPos(supportPos); // That's all the CloseOuts, flanges and Supports done. } // End of loop over layers. // Now come the layer independent placements. // The insulating stuff agdd::PosXYZ * insulationCylPos = new agdd::PosXYZ; insulationCylPos->setVolume(insulationCyl); barrelCompos->addPos(insulationCylPos); agdd::PosXYZ * posInsulationEndPos = new agdd::PosXYZ; agdd::PosXYZ * negInsulationEndPos = new agdd::PosXYZ; posInsulationEndPos->setVolume(insulationEnd); negInsulationEndPos->setVolume(insulationEnd); posInsulationEndPos->setXYZ(0., 0., +(hLen-tckIso/2.)); negInsulationEndPos->setXYZ(0., 0., -(hLen-tckIso/2.)); barrelCompos->addPos(posInsulationEndPos); barrelCompos->addPos(negInsulationEndPos); agdd::PosXYZ * tempPos = new agdd::PosXYZ; tempPos->setVolume(barrelModule); barrelCompos->addPos(tempPos); } // That was the end of the Barrel and skis. }} // This is where the old SCT.geo.hh ended return outStruct; };