//========================================================================== // AIDA Detector description implementation //-------------------------------------------------------------------------- // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) // All rights reserved. // // For the licensing terms see $DD4hepINSTALL/LICENSE. // For the list of contributors see $DD4hepINSTALL/doc/CREDITS. // // Author : M.Frank // //========================================================================== // // Specialized generic detector constructor // //========================================================================== // Framework include files #include "DD4hep/DetFactoryHelper.h" #include "DD4hep/Printout.h" #include "DDCMS/DDCMSPlugins.h" // C/C++ include files #include <sstream> using namespace std; using namespace dd4hep; using namespace dd4hep::detail; using namespace dd4hep::cms; static long create_element(Detector& description, ParsingContext& ctxt, xml_h e, SensitiveDetector& /* sens */) { stringstream str; PlacedVolume pv; Namespace ns(ctxt, e, true); AlgoArguments args(ctxt, e); string parentName = args.parentName(); printout(INFO,"DDCMS","+++ Parsing arguments for Algorithm:%-24s rParent:%s", args.name.c_str(), parentName.c_str()); string genMat = args.value<string>("GeneralMaterial"); int number = args.value<int>("Ladders"); double layerDz = args.value<double>("LayerDz"); double sensorEdge= args.value<double>("SensorEdge"); double coolDz = args.value<double>("CoolDz"); double coolWidth = args.value<double>("CoolWidth"); double coolSide = args.value<double>("CoolSide"); double coolThick = args.value<double>("CoolThick"); double coolDist = args.value<double>("CoolDist"); string coolMat = args.value<string>("CoolMaterial"); string tubeMat = args.value<string>("CoolTubeMaterial"); str << "Parent " << parentName << " NameSpace " << ns.name << "\n" << "\tLadders " << number << "\tGeneral Material " << genMat << "\tLength " << layerDz << "\tSensorEdge " << sensorEdge << "\tSpecification of Cooling Pieces:\n" << "\tLength " << coolDz << " Width " << coolWidth << " Side " << coolSide << " Thickness of Shell " << coolThick << " Radial distance " << coolDist << " Materials " << coolMat << ", " << tubeMat; printout(INFO,"DDPixBarLayerAlgo",str); vector<string> ladder = args.value<vector<string> >("LadderName"); vector<double> ladderWidth = args.value<vector<double> >("LadderWidth"); vector<double> ladderThick = args.value<vector<double> >("LadderThick"); str << "Full Ladder " << ladder[0] << " width/thickness " << ladderWidth[0] << ", " << ladderThick[0] << "\tHalf Ladder " << ladder[1] << " width/thickness " << ladderWidth[1] << ", " << ladderThick[1]; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); string mother = parentName; const std::string &idName = mother; double dphi = CLHEP::twopi/number; double d2 = 0.5*coolWidth; double d1 = d2 - coolSide*sin(0.5*dphi); double x1 = (d1+d2)/(2.*sin(0.5*dphi)); double x2 = coolDist*sin(0.5*dphi); double rmin = (coolDist-0.5*(d1+d2))*cos(0.5*dphi)-0.5*ladderThick[0]; double rmax = (coolDist+0.5*(d1+d2))*cos(0.5*dphi)+0.5*ladderThick[0]; double rmxh = rmax - 0.5*ladderThick[0] + ladderThick[1]; str << "Rmin/Rmax " << rmin << ", " << rmax << " d1/d2 " << d1 << ", " << d2 << " x1/x2 " << x1 << ", " << x2; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); double rtmi = rmin + 0.5*ladderThick[0] - ladderThick[1]; double rtmx = sqrt(rmxh*rmxh+ladderWidth[1]*ladderWidth[1]); Solid solid = Tube(rtmi, rtmx, 0.5*layerDz, 0, CLHEP::twopi); solid.setName(idName); str.str(""); str << "IDname "<< idName << " Tubs made of " << genMat << " from 0 to " << CLHEP::twopi/CLHEP::deg << " with Rin " << rtmi << " Rout " << rtmx << " ZHalf " << 0.5*layerDz; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); Volume layer(solid.name(), solid, ns.material(genMat)); double rr = 0.5*(rmax+rmin); double dr = 0.5*(rmax-rmin); double h1 = 0.5*coolSide*cos(0.5*dphi); std::string name = idName + "CoolTube"; solid = Trap(0.5*coolDz, 0, 0, h1, d2, d1, 0, h1, d2, d1, 0); solid.setName(idName+"CoolTube"); str << "Solid " << solid.name() << " Trap made of " << tubeMat << " of dimensions " << 0.5*coolDz << ", 0, 0, " << h1 << ", " << d2 << ", " << d1 << ", 0, " << h1 << ", " << d2 << ", " << d1 << ", 0"; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); Volume coolTube(solid.name(), solid, description.material(tubeMat)); h1 -= coolThick; d1 -= coolThick; d2 -= coolThick; solid = Trap(0.5*coolDz, 0, 0, h1, d2, d1, 0, h1, d2, d1, 0); solid.setName(idName + "Coolant"); str << "Solid " << solid.name() << " Trap made of " << coolMat << " of dimensions " << 0.5*coolDz << ", 0, 0, " << h1 << ", " << d2 << ", " << d1 << ", 0, " << h1 << ", " << d2 << ", " << d1 << ", 0"; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); Volume cool(solid.name(), solid, description.material(coolMat)); //cpv.position(cool, coolTube, 1, DDTranslation(0.0, 0.0, 0.0), DDRotation()); pv = coolTube.placeVolume(cool); str << "Cool " << cool.name() << " number 1 positioned in " << coolTube.name() << " at (0,0,0) with no rotation"; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); string ladderFull = ladder[0]; string ladderHalf = ladder[1]; int nphi=number/2, copy=1, iup=-1; double phi0 = 90*CLHEP::deg; Volume ladderHalfVol = ns.volume(ladderHalf); Volume ladderFullVol = ns.volume(ladderFull); for (int i=0; i<number; i++) { double phi = phi0 + i*dphi; double phix, phiy, rrr, xx; std::string rots; Position tran; Rotation3D rot; if (i == 0 || i == nphi) { rrr = rr + dr + 0.5*(ladderThick[1]-ladderThick[0]); xx = (0.5*ladderWidth[1] - sensorEdge) * sin(phi); tran = Position(xx, rrr*sin(phi), 0); rots = idName + std::to_string(copy); phix = phi-90*CLHEP::deg; phiy = 90*CLHEP::deg+phix; str << "Creating a new " << "rotation: " << rots << "\t90., " << phix/CLHEP::deg << ", 90.," << phiy/CLHEP::deg << ", 0, 0"; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); rot = make_rotation3D(90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.); //cpv.position(ladderHalf, layer, copy, tran, rot); pv = layer.placeVolume(ladderHalfVol, Transform3D(rot,tran)); if ( !pv.isValid() ) { } str << "ladderHalfVol: " << ladderHalfVol.name() << " number " << copy << " positioned in " << layer.name() << " at " << tran << " with " << rot; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); copy++; iup = -1; rrr = rr - dr - 0.5*(ladderThick[1]-ladderThick[0]); tran = Position(-xx, rrr*sin(phi), 0); rots = idName + std::to_string(copy); phix = phi+90*CLHEP::deg; phiy = 90*CLHEP::deg+phix; str << "Creating a new rotation: " << rots << "\t90., " << phix/CLHEP::deg << ", 90.," << phiy/CLHEP::deg << ", 0, 0"; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); rot = make_rotation3D(90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.); //cpv.position(ladderHalf, layer, copy, tran, rot); pv = layer.placeVolume(ladderHalfVol, Transform3D(rot,tran)); if ( !pv.isValid() ) { } str << "ladderHalfVol: " << ladderHalfVol.name() << " number " << copy << " positioned in " << layer.name() << " at " << tran << " with " << rot; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); copy++; } else { iup =-iup; rrr = rr + iup*dr; tran = Position(rrr*cos(phi), rrr*sin(phi), 0); rots = idName + std::to_string(copy); if (iup > 0) phix = phi-90*CLHEP::deg; else phix = phi+90*CLHEP::deg; phiy = phix+90.*CLHEP::deg; str << "DDPixBarLayerAlgo test: Creating a new " << "rotation: " << rots << "\t90., " << phix/CLHEP::deg << ", 90.," << phiy/CLHEP::deg << ", 0, 0"; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); rot = make_rotation3D(90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.); //cpv.position(ladderFull, layer, copy, tran, rot); pv = layer.placeVolume(ladderFullVol, Transform3D(rot,tran)); if ( !pv.isValid() ) { } str << "test: " << ladderFullVol.name() << " number " << copy << " positioned in " << layer.name() << " at " << tran << " with " << rot; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); copy++; } rrr = coolDist*cos(0.5*dphi); tran = Position(rrr*cos(phi)-x2*sin(phi), rrr*sin(phi)+x2*cos(phi), 0); rots = idName + std::to_string(i+100); phix = phi+0.5*dphi; if (iup > 0) phix += 180*CLHEP::deg; phiy = phix+90.*CLHEP::deg; str << "Creating a new rotation: " << rots << "\t90., " << phix/CLHEP::deg << ", 90.," << phiy/CLHEP::deg << ", 0, 0"; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); rot = make_rotation3D(90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.); //cpv.position(coolTube, layer, i+1, tran, rot); pv = layer.placeVolume(coolTube,Transform3D(rot,tran)); if ( !pv.isValid() ) { } str << "coolTube: " << coolTube.name() << " number " << i+1 << " positioned in " << layer.name() << " at " << tran << " with "<< rot; printout(ctxt.debug_algorithms ? ALWAYS : DEBUG,"DDPixBarLayerAlgo",str); } ns.addVolumeNS(layer); //nn.addVolume(assembly); printout(INFO,"DDPixBarLayerAlgo","Layer: %s assembly:%s",layer.name(),"---"); #if 0 string det_name = idName; Assembly assembly(det_name); // Now we have built the layer.....create the DetElement object DetElement det_elt(det_name,0); pv = assembly.placeVolume(layer); det_elt.setPlacement(pv); description.addDetector(det_elt); Volume motherVol = description.pickMotherVolume(det_elt); pv = motherVol.placeVolume(assembly); #endif return 1; } // first argument is the type from the xml file DECLARE_DDCMS_DETELEMENT(track_DDPixBarLayerAlgo,create_element)