Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /DD4hep/examples/DDCMS/src/plugins/DDTIDModulePosAlgo.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 //
0014 // Specialized generic detector constructor
0015 // 
0016 //==========================================================================
0017 
0018 // Framework include files
0019 #include "DD4hep/DetFactoryHelper.h"
0020 #include "DDCMS/DDCMSPlugins.h"
0021 
0022 using namespace std;
0023 using namespace dd4hep;
0024 using namespace dd4hep::cms;
0025 
0026 static long algorithm(Detector& /* description */,
0027                       ParsingContext& ctxt,
0028                       xml_h e,
0029                       SensitiveDetector& /* sens */)
0030 {
0031   Namespace      ns(ctxt, e, true);
0032   AlgoArguments  args(ctxt, e);
0033   string         parentName        = args.parentName();
0034   int            detectorN         = args.integer("DetectorNumber");         //Number of detectors
0035   double         detTilt           = args.dble("DetTilt");           //Tilt of stereo detector
0036   double         fullHeight        = args.dble("FullHeight");        //Height 
0037   string         boxFrameName      = args.str("BoxFrameName");      //Top frame Name
0038   double         boxFrameHeight    = args.dble("BoxFrameHeight");    //          height 
0039   double         boxFrameWidth     = args.dble("BoxFrameWidth");     //          width
0040   double         dlTop             = args.dble("DlTop");             //Width at top of wafer
0041   double         dlBottom          = args.dble("DlBottom");          //Width at bottom of wafer
0042   double         dlHybrid          = args.dble("DlHybrid");          //Width at the hybrid end
0043   vector<double> boxFrameZ         = args.vecDble("BoxFrameZ");         //              z-positions
0044   double         bottomFrameHeight = args.dble("BottomFrameHeight"); //Bottom of the frame
0045   double         bottomFrameOver   = args.dble("BottomFrameOver");   //              overlap
0046   double         topFrameHeight    = args.dble("TopFrameHeight");    //Top    of the frame
0047   double         topFrameOver      = args.dble("TopFrameOver");      //              overlap 
0048 
0049   vector<string> sideFrameName     = args.vecStr("SideFrameName");     //Side Frame    name
0050   vector<double> sideFrameZ        = args.vecDble("SideFrameZ");        //              z-positions
0051   vector<string> sideFrameRot      = args.vecStr("SideFrameRotation");      //              rotation matrix (required for correct positiong of the hole in the StereoR)
0052   double         sideFrameWidth    = args.dble("SideFrameWidth");    //              width
0053   double         sideFrameOver     = args.dble("SideFrameOver");     //              overlap (wrt wafer)
0054 
0055   vector<string> kaptonName        = args.vecStr("KaptonName");         //Kapton Circuit    name
0056   vector<double> kaptonZ           = args.vecDble("KaptonZ");           //              z-positions
0057   vector<string> kaptonRot         = args.vecStr("KaptonRotation");         //              rotation matrix (required for correct positiong of the hole in the StereoR)
0058   vector<string> waferName         = args.vecStr("WaferName");         //Wafer         name
0059   vector<double> waferZ            = args.vecDble("WaferZ");            //              z-positions
0060   vector<string> waferRot          = args.vecStr("WaferRotation");          //              rotation matrix
0061   string         hybridName        = args.str("HybridName");        //Hybrid        name
0062   double         hybridHeight      = args.dble("HybridHeight");      //              height
0063   vector<double> hybridZ           = args.vecDble("HybridZ");           //              z-positions
0064   vector<string> pitchName         = args.vecStr("PitchName");         //Pitch adapter rotation matrix
0065   double         pitchHeight       = args.dble("PitchHeight");       //              height
0066   vector<double> pitchZ            = args.vecDble("PitchZ");            //              z-positions
0067   vector<string> pitchRot          = args.vecStr("PitchRotation");          //              rotation matrix
0068   string         coolName          = args.str("CoolInsertName");        //Cool Insert   name
0069   double         coolHeight        = args.dble("CoolInsertHeight");      //              height
0070   double         coolZ             = args.dble("CoolInsertZ");           //              z-position
0071   double         coolWidth         = args.dble("CoolInsertWidth");       //              width
0072   vector<double> coolRadShift      = args.vecDble("CoolInsertShift");    //              
0073 
0074 
0075   bool           doSpacers         = ::toupper(args.str("DoSpacers")[0])!='N';      //Spacers (alumina) to be made (Should be "Yes" for DS modules only)
0076   string botSpacersName            = args.str("BottomSpacersName");   // Spacers at the "bottom" of the module
0077   double botSpacersHeight          = args.dble("BottomSpacersHeight");      //
0078   double botSpacersZ               = args.dble("BottomSpacersZ");           //              z-position
0079   string sidSpacersName            = args.str("SideSpacersName");   //Spacers at the "sides" of the module
0080   double sidSpacersHeight          = args.dble("SideSpacersHeight");   
0081   double sidSpacersZ               = args.dble("SideSpacersZ");           //              z-position
0082   double sidSpacersWidth           = args.dble("SideSpacersWidth");       //              width
0083   double sidSpacersRadShift        = args.dble("SideSpacersShift");    //              
0084 
0085   LogDebug("TIDGeom") << "Parent " << parentName
0086                       << " Detector Planes " << detectorN;
0087   LogDebug("TIDGeom") << "Detector Tilt " 
0088                       << detTilt/CLHEP::deg << " Height " << fullHeight 
0089                       << " dl(Top) " << dlTop << " dl(Bottom) " << dlBottom
0090                       << " dl(Hybrid) " << dlHybrid;
0091   LogDebug("TIDGeom") << boxFrameName  << " positioned at Z";
0092   for (int i = 0; i < detectorN; i++)
0093     LogDebug("TIDGeom") << "\tboxFrameZ[" << i << "] = " << boxFrameZ[i];
0094   LogDebug("TIDGeom") << "\t Extra Height at Bottom " << bottomFrameHeight
0095                       << " Overlap " <<bottomFrameOver;
0096   for (int i = 0; i < detectorN; i++)
0097     LogDebug("TIDGeom") << "\tsideFrame[" << i << "] = " << sideFrameName[i]
0098                         << " positioned at Z "<< sideFrameZ[i]
0099                         << " with rotation " << sideFrameRot[i];
0100   for (int i = 0; i < detectorN; i++)
0101     LogDebug("TIDGeom") << "\tkapton[" << i << "] = " << kaptonName[i]
0102                         << " positioned at Z "<< kaptonZ[i]
0103                         << " with rotation " << kaptonRot[i];
0104   for (int i = 0; i < detectorN; i++)
0105     LogDebug("TIDGeom") << waferName[i]
0106                         << " positioned at Z " << waferZ[i] 
0107                         << " with rotation " << waferRot[i];
0108   LogDebug("TIDGeom") << hybridName 
0109                       << " Height " << hybridHeight << " Z";
0110   for (int i = 0; i < detectorN; i++)
0111     LogDebug("TIDGeom") << "\thybridZ[" << i <<"] = " << hybridZ[i];
0112   LogDebug("TIDGeom") << "Pitch Adapter Height " << pitchHeight;
0113   for (int i = 0; i < detectorN; i++)
0114     LogDebug("TIDGeom") << pitchName[i] << " position at Z " << pitchZ[i] 
0115                         << " with rotation " << pitchRot[i];
0116   
0117   string name;
0118   double botfr;                   // width of side frame at the the bottom of the modules 
0119   double topfr;                   // width of side frame at the the top of the modules 
0120   double kaptonHeight;
0121   if (dlHybrid > dlTop) {
0122     // ring 1, ring 2
0123     topfr = topFrameHeight - pitchHeight - topFrameOver;      
0124     botfr = bottomFrameHeight - bottomFrameOver; 
0125     kaptonHeight = fullHeight + botfr;
0126   } else {
0127     // ring 3
0128     topfr = topFrameHeight - topFrameOver;      
0129     botfr = bottomFrameHeight - bottomFrameOver - pitchHeight; 
0130     kaptonHeight = fullHeight + topfr;
0131   }
0132 
0133   double sideFrameHeight = fullHeight + pitchHeight + botfr + topfr; 
0134   double zCenter     = 0.5 * (sideFrameHeight+boxFrameHeight); 
0135 
0136   // (Re) Compute the envelope for positioning Cool Inserts and Side Spacers (Alumina).
0137   double  sidfr = sideFrameWidth - sideFrameOver;      // width of side frame on the sides of module 
0138   double  dxbot = 0.5*dlBottom + sidfr;
0139   double  dxtop = 0.5*dlTop + sidfr;
0140   double  dxtopenv, dxbotenv;           // top/bot width of the module envelope trap
0141 
0142   double tanWafer=(dxtop-dxbot)/fullHeight; // 
0143   double thetaWafer = atan(tanWafer);       // 1/2 of the wafer wedge angle
0144 
0145   if (dlHybrid > dlTop) {
0146     // ring 1, ring 2
0147     dxtopenv = dxbot + (dxtop-dxbot)*(fullHeight+pitchHeight+topfr+hybridHeight)/fullHeight;
0148     dxbotenv = dxtop - (dxtop-dxbot)*(fullHeight+botfr)/fullHeight;
0149   } else {
0150     // ring 3
0151     dxtopenv = dxbot + (dxtop-dxbot)*(fullHeight+topfr)/fullHeight;
0152     dxbotenv = dxbot;
0153   }
0154 
0155   double tanEnv=(dxtopenv-dxbotenv)/(sideFrameHeight+boxFrameHeight); // 1/2 of the envelope wedge angle
0156 
0157   double xpos=0; double ypos=0; double zpos=0;
0158 
0159   // Cool Inserts
0160   name = coolName;
0161   ypos = coolZ;
0162 
0163   double     zCool;
0164   int        copy=0;
0165   Rotation3D rot; // should be different for different elements
0166   Volume     parentVol = ns.volume(parentName);
0167   
0168   for (int j1=0; j1<2; j1++){  // j1: 0 inserts below the hybrid
0169     //     1 inserts below the wafer
0170     if (dlHybrid > dlTop) {
0171       zCool = sideFrameHeight+boxFrameHeight-coolRadShift[j1];  
0172       if ( j1==0 ) zCool -= 0.5*coolHeight; 
0173     } else {
0174       zCool = coolRadShift[j1];  
0175       if ( j1==0 ) zCool += 0.5*coolHeight; 
0176     }
0177 
0178     if ( j1==0 ) {
0179       xpos = -0.5*(boxFrameWidth-coolWidth);
0180     } else {   
0181       xpos = -(dxbotenv+(zCool-0.5*coolHeight)*tanEnv-0.5*coolWidth);      
0182     }
0183            
0184     zpos = zCool-zCenter;
0185     for ( int j2=0; j2<2; j2++) {
0186       copy++;
0187       parentVol.placeVolume(ns.volume(name),copy,Position(xpos,ypos,zpos));
0188       LogDebug("TIDGeom") << name <<" number "
0189                           << copy << " positioned in " << parentName << " at "
0190                           << Position(xpos,ypos,zpos) << " with " << rot;
0191       xpos = -xpos;
0192     }
0193   }
0194 
0195   if ( doSpacers ) {
0196     // Bottom Spacers (Alumina)
0197     name = botSpacersName;
0198     ypos = botSpacersZ;
0199     double zBotSpacers;
0200     if (dlHybrid > dlTop) {
0201       zBotSpacers = sideFrameHeight+boxFrameHeight-0.5*botSpacersHeight;
0202     } else {
0203       zBotSpacers = 0.5*botSpacersHeight;
0204     }
0205     zpos = zBotSpacers - zCenter; 
0206     parentVol.placeVolume(ns.volume(name),1,Position(0.0,ypos,zpos));
0207     LogDebug("TIDGeom") << name <<" number "
0208                         << 1 << " positioned in " << parentName << " at "
0209                         << Position(0.0,ypos,zpos) << " with no rotation";          
0210     // Side Spacers (Alumina)
0211     name = sidSpacersName;
0212     ypos = sidSpacersZ;
0213     double zSideSpacers;
0214     if (dlHybrid > dlTop) {
0215       zSideSpacers = sideFrameHeight+boxFrameHeight-sidSpacersRadShift;
0216     } else {
0217       zSideSpacers = sidSpacersRadShift;
0218     }
0219     zpos = zSideSpacers - zCenter; 
0220     
0221     copy=0;
0222     xpos = dxbotenv+(zSideSpacers-0.5*sidSpacersHeight)*tanEnv-0.5*sidSpacersWidth+sideFrameOver;      
0223 
0224     double phiy = 0e0, phiz = 0e0;
0225     double phix=0.*CLHEP::deg; phiy=90.*CLHEP::deg; phiz=0.*CLHEP::deg;
0226 
0227     double thetax = 0e0;
0228     double thetay = 90.*CLHEP::deg;
0229     double thetaz = thetaWafer;
0230 
0231     for (int j1=0; j1<2; j1++){
0232       copy++; 
0233       // tilt Side Spacers (parallel to Side Frame)
0234       thetax = 90.*CLHEP::deg+thetaz;
0235       rot = make_rotation3D(thetax, phix, thetay, phiy, thetaz, phiz);
0236       parentVol.placeVolume(ns.volume(name),copy,Transform3D(rot,Position(xpos,ypos,zpos)));
0237       LogDebug("TIDGeom") << name <<" number " << copy << " positioned in " << parentName << " at "
0238                           << Position(xpos,ypos,zpos) << " with " << rot;
0239       xpos   = -xpos;
0240       thetaz = -thetaz;
0241     }
0242   }
0243 
0244   // Loop over detectors to be placed
0245   for (int k = 0; k < detectorN; k++) {
0246     // Wafer
0247     name = waferName[k];
0248     xpos=0; 
0249     ypos = waferZ[k];
0250     double zWafer;
0251     if (dlHybrid > dlTop) {
0252       zWafer = botfr+0.5*fullHeight;
0253     } else {
0254       zWafer = boxFrameHeight+botfr+pitchHeight+0.5*fullHeight;
0255     }
0256     zpos = zWafer - zCenter;
0257     Position tran(xpos, ypos, zpos);
0258     rot = ns.rotation(waferRot[k]);
0259     
0260     parentVol.placeVolume(ns.volume(name),k+1,Transform3D(rot,tran)); // copyNr=k+1
0261     LogDebug("TIDGeom") << name <<" number " << k+1 << " positioned in " << parentName << " at "
0262                         << tran << " with " << rot;
0263 
0264     //Pitch Adapter
0265     name = pitchName[k];
0266     if (k == 0) {
0267       xpos = 0;
0268     } else {
0269       xpos = 0.5 * fullHeight * sin(detTilt);
0270     }
0271     ypos = pitchZ[k];
0272     double zPitch;
0273     if (dlHybrid > dlTop) {
0274       zPitch = botfr+fullHeight+0.5*pitchHeight;
0275     } else {
0276       zPitch = boxFrameHeight+botfr+0.5*pitchHeight;
0277     }
0278     zpos = zPitch - zCenter;
0279     rot = ns.rotation(pitchRot[k]);
0280     tran = Position(xpos,ypos,zpos);
0281     parentVol.placeVolume(ns.volume(name),k+1,Transform3D(rot,tran)); // copyNr=k+1
0282     LogDebug("TIDGeom") << name <<" number " << k+1 << " positioned in " << parentName << " at "
0283                         << tran << " with " << rot;
0284 
0285     // Hybrid 
0286     name = hybridName;
0287     ypos = hybridZ[k];
0288     double zHybrid;
0289     if (dlHybrid > dlTop) {
0290       zHybrid = botfr+fullHeight+pitchHeight+0.5*hybridHeight;
0291     } else {
0292       zHybrid = 0.5*hybridHeight;
0293     }
0294     zpos = zHybrid - zCenter;
0295     tran = Position(0,ypos,zpos);
0296     parentVol.placeVolume(ns.volume(name),k+1,tran); // copyNr=k+1
0297     LogDebug("TIDGeom") << name <<" number "  << k+1 << " positioned in " << parentName << " at " << tran;
0298 
0299     // Box frame
0300     name = boxFrameName;
0301     ypos = boxFrameZ[k];
0302     double zBoxFrame;
0303     if (dlHybrid > dlTop) {
0304       zBoxFrame = sideFrameHeight+0.5*boxFrameHeight;
0305     } else {
0306       zBoxFrame = 0.5*boxFrameHeight;
0307     }
0308     zpos = zBoxFrame - zCenter;
0309     tran = Position(0,ypos,zpos);
0310     parentVol.placeVolume(ns.volume(name),k+1,tran); // copyNr=k+1
0311     LogDebug("TIDGeom") << name <<" number " << k+1 << " positioned in " << parentName << " at " << tran;
0312 
0313     // Side frame
0314     name = sideFrameName[k];
0315     ypos = sideFrameZ[k];
0316     double zSideFrame;
0317     if (dlHybrid > dlTop) {
0318       zSideFrame = 0.5*sideFrameHeight;
0319     } else {
0320       zSideFrame = boxFrameHeight+0.5*sideFrameHeight;
0321     }
0322     zpos = zSideFrame-zCenter;
0323     rot  = ns.rotation(sideFrameRot[k]);
0324     tran = Position(0,ypos,zpos);
0325     parentVol.placeVolume(ns.volume(name),k+1,Transform3D(rot,tran));
0326     LogDebug("TIDGeom") << name <<" number "
0327                         << k+1 << " positioned in " << parentName << " at "
0328                         << tran << " with " << rot;
0329     // Kapton circuit
0330     name = kaptonName[k];
0331     ypos = kaptonZ[k];
0332     double zKapton;
0333     double kaptonExtraHeight=0;
0334     if (dlHybrid > dlTop) {
0335       if ( k == 1 ) kaptonExtraHeight = dlTop*sin(detTilt)-fullHeight*(1-cos(detTilt));
0336       kaptonExtraHeight = 0.5*fabs(kaptonExtraHeight);
0337       zKapton = 0.5*(kaptonHeight+kaptonExtraHeight);
0338     } else {
0339       if ( k == 1 ) kaptonExtraHeight = dlBottom*sin(detTilt)-fullHeight*(1-cos(detTilt));
0340       kaptonExtraHeight = 0.5*fabs(kaptonExtraHeight);
0341       zKapton = boxFrameHeight+sideFrameHeight-0.5*(kaptonHeight+kaptonExtraHeight);
0342     }
0343     zpos = zKapton-zCenter;
0344     rot  = ns.rotation(kaptonRot[k]);
0345     tran = Position(0,ypos,zpos);
0346     parentVol.placeVolume(ns.volume(name),k+1,Transform3D(rot,tran));
0347     LogDebug("TIDGeom") << name <<" number "
0348                         << k+1 << " positioned in " << parentName << " at "
0349                         << tran << " with " << rot;
0350   }
0351   LogDebug("TIDGeom") << "<<== End of DDTIDModulePosAlgo positioning ...";
0352   return 1;
0353 }
0354 
0355 // first argument is the type from the xml file
0356 DECLARE_DDCMS_DETELEMENT(DDCMS_track_DDTIDModulePosAlgo,algorithm)