CMS 3D CMS Logo

Public Member Functions | Private Member Functions | Private Attributes

CSCGeometryBuilder Class Reference

#include <CSCGeometryBuilder.h>

List of all members.

Public Member Functions

void build (boost::shared_ptr< CSCGeometry > theGeometry, const RecoIdealGeometry &rig, const CSCRecoDigiParameters &cscpars)
 Build the geometry.
 CSCGeometryBuilder ()
 Constructor.
virtual ~CSCGeometryBuilder ()
 Destructor.

Private Member Functions

void buildChamber (boost::shared_ptr< CSCGeometry > theGeometry, CSCDetId chamberId, const std::vector< float > &fpar, const std::vector< float > &fupar, const std::vector< float > &gtran, const std::vector< float > &grmat, const CSCWireGroupPackage &wg)
 Build one CSC chamber, and its component layers, and add them to the geometry.

Private Attributes

const std::string myName

Detailed Description

Build the CSCGeometry from the DDD description.

Author:
Tim Cox

Definition at line 22 of file CSCGeometryBuilder.h.


Constructor & Destructor Documentation

CSCGeometryBuilder::CSCGeometryBuilder ( )

Constructor.

Definition at line 18 of file CSCGeometryBuilder.cc.

: myName("CSCGeometryBuilder"){}
CSCGeometryBuilder::~CSCGeometryBuilder ( ) [virtual]

Destructor.

Definition at line 21 of file CSCGeometryBuilder.cc.

{}

Member Function Documentation

void CSCGeometryBuilder::build ( boost::shared_ptr< CSCGeometry theGeometry,
const RecoIdealGeometry rig,
const CSCRecoDigiParameters cscpars 
)

Build the geometry.

Definition at line 24 of file CSCGeometryBuilder.cc.

References CSCWireGroupPackage::alignmentPinToFirstWire, buildChamber(), CSCWireGroupPackage::consecutiveGroups, CSCDetId, cond::rpcobgas::detid, RecoIdealGeometry::detIds(), i, CSCWireGroupPackage::lengthOfWirePlane, LogTrace, myName, CSCWireGroupPackage::narrowWidthOfWirePlane, CSCWireGroupPackage::numberOfGroups, CSCRecoDigiParameters::pChamberType, CSCRecoDigiParameters::pfupars, CSCRecoDigiParameters::pUserParOffset, CSCRecoDigiParameters::pUserParSize, CSCDetId::ring(), RecoIdealGeometry::rotEnd(), RecoIdealGeometry::rotStart(), RecoIdealGeometry::shapeEnd(), RecoIdealGeometry::shapeStart(), CSCDetId::station(), RecoIdealGeometry::tranEnd(), RecoIdealGeometry::tranStart(), CSCChamberSpecs::whatChamberType(), CSCWireGroupPackage::wideWidthOfWirePlane, CSCWireGroupPackage::wiresInEachGroup, and CSCWireGroupPackage::wireSpacing.

Referenced by CSCGeometryBuilderFromDDD::build(), buildChamber(), and CSCGeometryESModule::geometryCallback_().

                                                                         {

  //  CSCGeometry* theGeometry = new CSCGeometry;

  std::vector<float> fpar;
  std::vector<float> gtran;
  std::vector<float> grmat;
  std::vector<float> fupar;
  std::vector<double>::const_iterator it, endIt;
  const std::vector<DetId>& detids(rig.detIds());

  for ( size_t idt = 0; idt < detids.size(); ++idt) {
    CSCDetId detid = CSCDetId( detids[idt] );
    //    int jendcap  = detid.endcap();
    int jstation = detid.station();
    int jring    = detid.ring();
    //    int jchamber = detid.chamber();

    endIt = rig.shapeEnd(idt);
    fpar.clear();
    for ( it = rig.shapeStart(idt); it != endIt; ++it) {
      fpar.push_back( (float)(*it) );
    }

    gtran.clear();
    endIt = rig.tranEnd(idt);
    for ( it = rig.tranStart(idt); it != endIt; ++it ) {
      gtran.push_back((float)(*it));
    }
    grmat.clear();
    endIt = rig.rotEnd(idt);
    for ( it = rig.rotStart(idt) ; it != endIt; ++it ) {
      grmat.push_back((float)(*it));
    }

    // get the chamber type from existing info
    int chamberType = CSCChamberSpecs::whatChamberType( jstation, jring );
    //    std::cout << "Chamber type = " << chamberType << std::endl;
    size_t cs = 0;
    //       assert ( cscpars.pCSCDetIds.size() != 0 );
    assert ( cscpars.pChamberType.size() != 0 );
    //       while (cs < cscpars.pCSCDetIds.size() && detid != cscpars.pCSCDetIds[cs]) {
    while (cs < cscpars.pChamberType.size() && chamberType != cscpars.pChamberType[cs]) {
      ++cs;
    }
    //       assert ( cs != cscpars.pCSCDetIds.size() );
    assert ( cs != cscpars.pChamberType.size() );
      
    // check the existence of the specs for this type WHY? Remove it...
    //    const CSCChamberSpecs* aSpecs = theGeometry->findSpecs( chamberType );
    size_t fu, numfuPars;
    CSCWireGroupPackage wg;
    fu = cscpars.pUserParOffset[cs];
    numfuPars = fu + 1 + size_t(cscpars.pfupars[fu]);

    // upars from db are now uparvals + wg info so we need to unwrap only part here first...
    LogTrace(myName) << myName << ": I think I have " << cscpars.pUserParSize[cs] << " values in pfupars (uparvals)." << std::endl;
    LogTrace(myName) << myName << ": For fupar I will start at " << cscpars.pUserParOffset[cs] + 1 
                     << " in pfupars and go to " << numfuPars << "." << std::endl;
    //    if ( aSpecs == 0 ) { 
      for ( ++fu; fu < numfuPars; ++fu ) {
        LogTrace(myName) << myName << ": pfupars[" << fu << "]=" << cscpars.pfupars[fu] << std::endl;
        fupar.push_back(cscpars.pfupars[fu]);
      }
//     } else {
//       fu = fu + numfuPars + 1;
//     }
    // now, we need to start from "here" at fu to go on and build wg...
    wg.wireSpacing = cscpars.pfupars[fu++];
    wg.alignmentPinToFirstWire = cscpars.pfupars[fu++];
    wg.numberOfGroups = int(cscpars.pfupars[fu++]);
    wg.narrowWidthOfWirePlane = cscpars.pfupars[fu++];
    wg.wideWidthOfWirePlane = cscpars.pfupars[fu++];
    wg.lengthOfWirePlane = cscpars.pfupars[fu++];
    size_t numgrp = static_cast<size_t>(cscpars.pfupars[fu]);
    size_t maxFu = fu + 1 + numgrp;
    fu++;
    for ( ;fu < maxFu; ++fu ) {
      wg.wiresInEachGroup.push_back(int(cscpars.pfupars[fu]));
    } 
    maxFu = fu + numgrp;
    //stupid comment    // MEC: 2008-04-30: decided I need to have wg every time unless whole wg idea is re-worked.
    //       std::cout << " fu = " << fu << " going to maxFu = " << maxFu << std::endl;
    for ( ;fu < maxFu; ++fu ) {
      wg.consecutiveGroups.push_back(int(cscpars.pfupars[fu]));
    } 
          
    if ( wg.numberOfGroups != 0 ) {
      LogTrace(myName) << myName  << ": TotNumWireGroups     = " << wg.numberOfGroups ;
      LogTrace(myName) << myName  << ": WireSpacing          = " << wg.wireSpacing ;
      LogTrace(myName) << myName  << ": AlignmentPinToFirstWire = " << wg.alignmentPinToFirstWire ;
      LogTrace(myName) << myName  << ": Narrow width of wire plane = " << wg.narrowWidthOfWirePlane ;
      LogTrace(myName) << myName  << ": Wide width of wire plane = " << wg.wideWidthOfWirePlane ;
      LogTrace(myName) << myName  << ": Length in y of wire plane = " << wg.lengthOfWirePlane ;
      LogTrace(myName) << myName  << ": wg.consecutiveGroups.size() = " << wg.consecutiveGroups.size() ;
      LogTrace(myName) << myName  << ": wg.wiresInEachGroup.size() = " << wg.wiresInEachGroup.size() ;
      LogTrace(myName) << myName  << ": \tNumGroups\tWiresInGroup" ;
      for (size_t i = 0; i < wg.consecutiveGroups.size(); i++) {
        LogTrace(myName) << myName  << " \t" << wg.consecutiveGroups[i] << "\t\t" << wg.wiresInEachGroup[i] ;
      }
    } else {
      LogTrace(myName) << myName  << ": DDD is MISSING SpecPars for wire groups" ;
    }
    LogTrace(myName) << myName << ": end of wire group info. " ;
      
    //      CSCWireGroupPackage wg = cscpars.pWGPs[cs];
    // Are we going to apply centre-to-intersection offsets, even if values exist in the specs file?
    if ( !theGeometry->centreTIOffsets() ) fupar[30] = 0.;  // reset to zero if flagged 'off'
      
    buildChamber (theGeometry, detid, fpar, fupar, gtran, grmat, wg ); //, cscpars.pWGPs[cs] );
    fupar.clear();
  }
  //    return theGeometry;  
}
void CSCGeometryBuilder::buildChamber ( boost::shared_ptr< CSCGeometry theGeometry,
CSCDetId  chamberId,
const std::vector< float > &  fpar,
const std::vector< float > &  fupar,
const std::vector< float > &  gtran,
const std::vector< float > &  grmat,
const CSCWireGroupPackage wg 
) [private]

Build one CSC chamber, and its component layers, and add them to the geometry.

Definition at line 141 of file CSCGeometryBuilder.cc.

References BoundSurface::bounds(), build(), CSCDetId::chamber(), gather_cfg::cout, CSCDetId, CSCDetId::endcap(), CSCChamberSpecs::evenLayerGeometry(), relativeConstraints::geom, j, CSCDetId::layer(), LogTrace, myName, CSCChamberSpecs::oddLayerGeometry(), TrapezoidalPlaneBounds::parameters(), CSCDetId::ring(), TkRotation< T >::rotateAxes(), CSCDetId::station(), GeomDet::surface(), Bounds::thickness(), and CSCChamberSpecs::whatChamberType().

Referenced by build().

                                         {

  LogTrace(myName) << myName  << ": entering buildChamber" ;

  int jend   = chamberId.endcap();
  int jstat  = chamberId.station();
  int jring  = chamberId.ring();
  int jch    = chamberId.chamber();
  int jlay   = chamberId.layer();

  if (jlay != 0 ) edm::LogWarning(myName) << "Error! CSCGeometryBuilderFromDDD was fed layer id = " << jlay << "\n";

  const size_t kNpar = 4;
  if ( fpar.size() != kNpar ) 
    edm::LogError(myName) << "Error, expected npar=" 
              << kNpar << ", found npar=" << fpar.size() << std::endl;

  LogTrace(myName) << myName  << ":  E" << jend << " S" << jstat << " R" << jring <<
    " C" << jch << " L" << jlay ;
  LogTrace(myName) << myName  << ": npar=" << fpar.size() << " hB=" << fpar[0] 
                  << " hT=" << fpar[1] << " hD=" << fpar[2] << " hH=" << fpar[3] ;
  LogTrace(myName) << myName  << ": gtran[0,1,2]=" << gtran[0] << " " << gtran[1] << " " << gtran[2] ;
  LogTrace(myName) << myName  << ": grmat[0-8]=" << grmat[0] << " " << grmat[1] << " " << grmat[2] << " "
         << grmat[3] << " " << grmat[4] << " " << grmat[5] << " "
                  << grmat[6] << " " << grmat[7] << " " << grmat[8] ;
  LogTrace(myName) << myName  << ": nupar=" << fupar.size() << " upar[0]=" << fupar[0]
                   << " upar[" << fupar.size()-1 << "]=" << fupar[fupar.size()-1];


  CSCChamber* chamber = const_cast<CSCChamber*>(theGeometry->chamber( chamberId ));
  if ( chamber ){
  }
  else { // this chamber not yet built/stored
  
    LogTrace(myName) << myName <<": CSCChamberSpecs::build requested for ME" << jstat << jring ;
     int chamberType = CSCChamberSpecs::whatChamberType( jstat, jring );
     const CSCChamberSpecs* aSpecs = theGeometry->findSpecs( chamberType );
//     //    CSCChamberSpecs* aSpecs = CSCChamberSpecs::specs( chamberType );
//     if ( aSpecs == 0 ) aSpecs = theGeometry->buildSpecs( chamberType, fpar, fupar, wg );
    //                 aSpecs = CSCChamberSpecs::build( chamberType, fpar, fupar, wg );
    if ( fupar.size() != 0 && aSpecs == 0 ) {
      // make new one:
      aSpecs = theGeometry->buildSpecs (chamberType, fpar, fupar, wg);
    } else if ( fupar.size() == 0 && aSpecs == 0 ) {
        std::cout << "SHOULD BE THROW? Error, wg and/or fupar size are 0 BUT this Chamber Spec has not been built!" << std::endl;
    }
//  else if (fupar.size() != 0 && aSpecs != 0 ) {
//       std::cout << "SHOULD BE THROW? Error, a Chamber Specs was found AND still the fupar and/or wg were/was non-zero! " << std::endl;
//     }


   // Build a Transformation out of GEANT gtran and grmat...
   // These are used to transform a point in the local reference frame
   // of a subdetector to the global frame of CMS by
   //         (grmat)^(-1)*local + (gtran)
   // The corresponding transformation from global to local is
   //         (grmat)*(global - gtran)
 
    BoundSurface::RotationType aRot( grmat[0], grmat[1], grmat[2], 
                                     grmat[3], grmat[4], grmat[5],
                                     grmat[6], grmat[7], grmat[8] );

   // This rotation from GEANT considers the detector face as the x-z plane.
   // We want this to be the local x-y plane.
   // Furthermore, the -z_global endcap has LH local coordinates, since it is built
   // in GEANT as a *reflection* of the +z_global endcap.
   // So we need to rotate, and in -z flip local x.

   // aRot.rotateAxes will transform aRot in place so that it becomes
   // applicable to the new local coordinates: detector face in x-y plane
   // looking out along z, in either endcap.

   // The interface for rotateAxes specifies 'new' X,Y,Z but the
   // implementation deals with them as the 'old'.

    Basic3DVector<float> oldX( 1., 0.,  0. );
    Basic3DVector<float> oldY( 0., 0., -1. );
    Basic3DVector<float> oldZ( 0., 1.,  0. );

    if ( gtran[2]<0. ) oldX *= -1; 

    aRot.rotateAxes( oldX, oldY, oldZ );
      
   // Need to know z of layers w.r.t to z of centre of chamber. 

    float frameThickness     = fupar[31]/10.; // mm -> cm
    float gapThickness       = fupar[32]/10.; // mm -> cm
    float panelThickness     = fupar[33]/10.; // mm -> cm
    float zAverageAGVtoAF    = fupar[34]/10.; // mm -> cm

    float layerThickness = gapThickness; // consider the layer to be the gas gap
    float layerSeparation = gapThickness + panelThickness; // centre-to-centre of neighbouring layers

    float chamberThickness = 7.*panelThickness + 6.*gapThickness + 2.*frameThickness ; // chamber frame thickness
    float hChamberThickness = chamberThickness/2.; // @@ should match value returned from DDD directly

    // distAverageAGVtoAF is offset between centre of chamber (AF) and (L1+L6)/2 (average AGVs) 
    // where AF = AluminumFrame and AGV=ActiveGasVolume (volume names in DDD).
    // It is signed based on global z values: zc - (zl1+zl6)/2
   
    // Local z values w.r.t. AF...
    //     z of wires in layer 1 = z_w1 = +/- zAverageAGVtoAF + 2.5*layerSeparation; // layer 1 is at most +ve local z
    // The sign in '+/-' depends on relative directions of local and global z. 
    // It is '-' if they are the same direction, and '+' if opposite directions.
    //     z of wires in layer N   = z_wN = z_w1 - (N-1)*layerSeparation; 
    //     z of strips in layer N  = z_sN = z_wN + gapThickness/2.; @@ BEWARE: need to check if it should be '-gapThickness/2' !

    // Set dimensions of trapezoidal chamber volume 
    // N.B. apothem is 4th in fpar but 3rd in ctor 

    // hChamberThickness and fpar[2] should be the same - but using the above value at least shows
    // how chamber structure works

    //    TrapezoidalPlaneBounds* bounds =  new TrapezoidalPlaneBounds( fpar[0], fpar[1], fpar[3], fpar[2] ); 
    TrapezoidalPlaneBounds* bounds =  new TrapezoidalPlaneBounds( fpar[0], fpar[1], fpar[3], hChamberThickness ); 

   // Centre of chamber in z is specified in DDD
    Surface::PositionType aVec( gtran[0], gtran[1], gtran[2] ); 

    BoundPlane::BoundPlanePointer plane = BoundPlane::build(aVec, aRot, bounds); 
    delete bounds; // bounds cloned by BoundPlane, so we can delete it

    CSCChamber* chamber = new CSCChamber( plane, chamberId, aSpecs );
    theGeometry->addChamber( chamber ); 

    LogTrace(myName) << myName << ": Create chamber E" << jend << " S" << jstat 
                     << " R" << jring << " C" << jch 
                     << " z=" << gtran[2]
                     << " t/2=" << fpar[2] << " (DDD) or " << hChamberThickness 
                     << " (specs) adr=" << chamber ;

    // Create the component layers of this chamber   
    // We're taking the z as the z of the wire plane within the layer (middle of gas gap)

    // Specify global z of layer by offsetting from centre of chamber: since layer 1 
    // is nearest to IP in stations 1/2 but layer 6 is nearest in stations 3/4, 
    // we need to adjust sign of offset appropriately...
    int localZwrtGlobalZ = +1;
    if ( (jend==1 && jstat<3 ) || ( jend==2 && jstat>2 ) ) localZwrtGlobalZ = -1;
    int globalZ = +1;
    if ( jend == 2 ) globalZ = -1;
//     int localZwrtGlobalZ = +1;
//     if ( (jend==1 && jstat<3 ) || ( jend==2 && jstat>2 ) ) localZwrtGlobalZ = -1;


    LogTrace(myName) << myName << ": layerSeparation=" << layerSeparation
                     << ", zAF-zAverageAGV="  << zAverageAGVtoAF
                     << ", localZwrtGlobalZ=" << localZwrtGlobalZ
                     << ", gtran[2]=" << gtran[2] ;

    for ( short j = 1; j <= 6; ++j ) {

      CSCDetId layerId = CSCDetId( jend, jstat, jring, jch, j );

      // extra-careful check that we haven't already built this layer
      const CSCLayer* cLayer = dynamic_cast<const CSCLayer*> (theGeometry->idToDet( layerId ) );

      if ( cLayer == 0 ) {

        // build the layer - need the chamber's specs and an appropriate layer-geometry
         const CSCChamberSpecs* aSpecs = chamber->specs();
         const CSCLayerGeometry* geom = 
                    (j%2 != 0) ? aSpecs->oddLayerGeometry( jend ) : 
                                 aSpecs->evenLayerGeometry( jend );

        // Build appropriate BoundPlane, based on parent chamber, with gas gap as thickness

        // centre of chamber is at global z = gtran[2]
        float zlayer = gtran[2] - globalZ*zAverageAGVtoAF + localZwrtGlobalZ*(3.5-j)*layerSeparation;

        BoundSurface::RotationType chamberRotation = chamber->surface().rotation();
        BoundPlane::PositionType layerPosition( gtran[0], gtran[1], zlayer );
        //        TrapezoidalPlaneBounds* bounds = new TrapezoidalPlaneBounds( *geom );
        //      std::vector<float> dims = bounds->parameters(); // returns hb, ht, d, a
        std::vector<float> dims = geom->parameters(); // returns hb, ht, d, a
        dims[2] = layerThickness/2.; // half-thickness required and note it is 3rd value in vector
        //        delete bounds;        
        //        bounds = new TrapezoidalPlaneBounds( dims[0], dims[1], dims[3], dims[2] );
        TrapezoidalPlaneBounds* bounds = new TrapezoidalPlaneBounds( dims[0], dims[1], dims[3], dims[2] );
        BoundPlane::BoundPlanePointer plane = BoundPlane::build(layerPosition, chamberRotation, bounds);
        delete bounds;

        CSCLayer* layer = new CSCLayer( plane, layerId, chamber, geom );

        LogTrace(myName) << myName << ": Create layer E" << jend << " S" << jstat 
                    << " R" << jring << " C" << jch << " L" << j
                    << " z=" << zlayer
                         << " t=" << layerThickness << " or " << layer->surface().bounds().thickness()
                    << " adr=" << layer << " layerGeom adr=" << geom ;

        chamber->addComponent(j, layer); 
        theGeometry->addLayer( layer );
      }
      else {
        edm::LogError(myName) << ": ERROR, layer " << j <<
            " for chamber = " << ( chamber->id() ) <<
            " already exists: layer address=" << cLayer <<
            " chamber address=" << chamber << "\n";
      }

    } // layer construction within chamber
  } // chamber construction
}

Member Data Documentation

const std::string CSCGeometryBuilder::myName [private]

Definition at line 49 of file CSCGeometryBuilder.h.

Referenced by build(), and buildChamber().