00001 #include "CSCGeometryBuilder.h"
00002
00003
00004
00005 #include <Geometry/CSCGeometry/interface/CSCGeometry.h>
00006
00007 #include <DataFormats/DetId/interface/DetId.h>
00008 #include <DataFormats/MuonDetId/interface/CSCDetId.h>
00009 #include <Geometry/CSCGeometry/src/CSCWireGroupPackage.h>
00010
00011 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00012
00013 #include <iostream>
00014 #include <iomanip>
00015 #include <algorithm>
00016 #include <vector>
00017
00018 CSCGeometryBuilder::CSCGeometryBuilder() : myName("CSCGeometryBuilder"){}
00019
00020
00021 CSCGeometryBuilder::~CSCGeometryBuilder(){}
00022
00023
00024 void CSCGeometryBuilder::build( boost::shared_ptr<CSCGeometry> theGeometry
00025 , const RecoIdealGeometry& rig
00026 , const CSCRecoDigiParameters& cscpars ) {
00027
00028
00029
00030 std::vector<float> fpar;
00031 std::vector<float> gtran;
00032 std::vector<float> grmat;
00033 std::vector<float> fupar;
00034 std::vector<double>::const_iterator it, endIt;
00035 const std::vector<DetId>& detids(rig.detIds());
00036
00037 for ( size_t idt = 0; idt < detids.size(); ++idt) {
00038 CSCDetId detid = CSCDetId( detids[idt] );
00039
00040 int jstation = detid.station();
00041 int jring = detid.ring();
00042
00043
00044 endIt = rig.shapeEnd(idt);
00045 fpar.clear();
00046 for ( it = rig.shapeStart(idt); it != endIt; ++it) {
00047 fpar.push_back( (float)(*it) );
00048 }
00049
00050 gtran.clear();
00051 endIt = rig.tranEnd(idt);
00052 for ( it = rig.tranStart(idt); it != endIt; ++it ) {
00053 gtran.push_back((float)(*it));
00054 }
00055 grmat.clear();
00056 endIt = rig.rotEnd(idt);
00057 for ( it = rig.rotStart(idt) ; it != endIt; ++it ) {
00058 grmat.push_back((float)(*it));
00059 }
00060
00061
00062 int chamberType = CSCChamberSpecs::whatChamberType( jstation, jring );
00063
00064 size_t cs = 0;
00065
00066 assert ( cscpars.pChamberType.size() != 0 );
00067
00068 while (cs < cscpars.pChamberType.size() && chamberType != cscpars.pChamberType[cs]) {
00069 ++cs;
00070 }
00071
00072 assert ( cs != cscpars.pChamberType.size() );
00073
00074
00075
00076 size_t fu, numfuPars;
00077 CSCWireGroupPackage wg;
00078 fu = cscpars.pUserParOffset[cs];
00079 numfuPars = fu + 1 + size_t(cscpars.pfupars[fu]);
00080
00081
00082 LogTrace(myName) << myName << ": I think I have " << cscpars.pUserParSize[cs] << " values in pfupars (uparvals)." << std::endl;
00083 LogTrace(myName) << myName << ": For fupar I will start at " << cscpars.pUserParOffset[cs] + 1
00084 << " in pfupars and go to " << numfuPars << "." << std::endl;
00085
00086 for ( ++fu; fu < numfuPars; ++fu ) {
00087 LogTrace(myName) << myName << ": pfupars[" << fu << "]=" << cscpars.pfupars[fu] << std::endl;
00088 fupar.push_back(cscpars.pfupars[fu]);
00089 }
00090
00091
00092
00093
00094 wg.wireSpacing = cscpars.pfupars[fu++];
00095 wg.alignmentPinToFirstWire = cscpars.pfupars[fu++];
00096 wg.numberOfGroups = int(cscpars.pfupars[fu++]);
00097 wg.narrowWidthOfWirePlane = cscpars.pfupars[fu++];
00098 wg.wideWidthOfWirePlane = cscpars.pfupars[fu++];
00099 wg.lengthOfWirePlane = cscpars.pfupars[fu++];
00100 size_t numgrp = static_cast<size_t>(cscpars.pfupars[fu]);
00101 size_t maxFu = fu + 1 + numgrp;
00102 fu++;
00103 for ( ;fu < maxFu; ++fu ) {
00104 wg.wiresInEachGroup.push_back(int(cscpars.pfupars[fu]));
00105 }
00106 maxFu = fu + numgrp;
00107
00108
00109 for ( ;fu < maxFu; ++fu ) {
00110 wg.consecutiveGroups.push_back(int(cscpars.pfupars[fu]));
00111 }
00112
00113 if ( wg.numberOfGroups != 0 ) {
00114 LogTrace(myName) << myName << ": TotNumWireGroups = " << wg.numberOfGroups ;
00115 LogTrace(myName) << myName << ": WireSpacing = " << wg.wireSpacing ;
00116 LogTrace(myName) << myName << ": AlignmentPinToFirstWire = " << wg.alignmentPinToFirstWire ;
00117 LogTrace(myName) << myName << ": Narrow width of wire plane = " << wg.narrowWidthOfWirePlane ;
00118 LogTrace(myName) << myName << ": Wide width of wire plane = " << wg.wideWidthOfWirePlane ;
00119 LogTrace(myName) << myName << ": Length in y of wire plane = " << wg.lengthOfWirePlane ;
00120 LogTrace(myName) << myName << ": wg.consecutiveGroups.size() = " << wg.consecutiveGroups.size() ;
00121 LogTrace(myName) << myName << ": wg.wiresInEachGroup.size() = " << wg.wiresInEachGroup.size() ;
00122 LogTrace(myName) << myName << ": \tNumGroups\tWiresInGroup" ;
00123 for (size_t i = 0; i < wg.consecutiveGroups.size(); i++) {
00124 LogTrace(myName) << myName << " \t" << wg.consecutiveGroups[i] << "\t\t" << wg.wiresInEachGroup[i] ;
00125 }
00126 } else {
00127 LogTrace(myName) << myName << ": DDD is MISSING SpecPars for wire groups" ;
00128 }
00129 LogTrace(myName) << myName << ": end of wire group info. " ;
00130
00131
00132
00133 if ( !theGeometry->centreTIOffsets() ) fupar[30] = 0.;
00134
00135 buildChamber (theGeometry, detid, fpar, fupar, gtran, grmat, wg );
00136 fupar.clear();
00137 }
00138
00139 }
00140
00141 void CSCGeometryBuilder::buildChamber (
00142 boost::shared_ptr<CSCGeometry> theGeometry
00143 , CSCDetId chamberId
00144 , const std::vector<float>& fpar
00145 , const std::vector<float>& fupar
00146 , const std::vector<float>& gtran
00147 , const std::vector<float>& grmat
00148 , const CSCWireGroupPackage& wg
00149 ) {
00150
00151 LogTrace(myName) << myName << ": entering buildChamber" ;
00152
00153 int jend = chamberId.endcap();
00154 int jstat = chamberId.station();
00155 int jring = chamberId.ring();
00156 int jch = chamberId.chamber();
00157 int jlay = chamberId.layer();
00158
00159 if (jlay != 0 ) edm::LogWarning(myName) << "Error! CSCGeometryBuilderFromDDD was fed layer id = " << jlay << "\n";
00160
00161 const size_t kNpar = 4;
00162 if ( fpar.size() != kNpar )
00163 edm::LogError(myName) << "Error, expected npar="
00164 << kNpar << ", found npar=" << fpar.size() << std::endl;
00165
00166 LogTrace(myName) << myName << ": E" << jend << " S" << jstat << " R" << jring <<
00167 " C" << jch << " L" << jlay ;
00168 LogTrace(myName) << myName << ": npar=" << fpar.size() << " hB=" << fpar[0]
00169 << " hT=" << fpar[1] << " hD=" << fpar[2] << " hH=" << fpar[3] ;
00170 LogTrace(myName) << myName << ": gtran[0,1,2]=" << gtran[0] << " " << gtran[1] << " " << gtran[2] ;
00171 LogTrace(myName) << myName << ": grmat[0-8]=" << grmat[0] << " " << grmat[1] << " " << grmat[2] << " "
00172 << grmat[3] << " " << grmat[4] << " " << grmat[5] << " "
00173 << grmat[6] << " " << grmat[7] << " " << grmat[8] ;
00174 LogTrace(myName) << myName << ": nupar=" << fupar.size() << " upar[0]=" << fupar[0]
00175 << " upar[" << fupar.size()-1 << "]=" << fupar[fupar.size()-1];
00176
00177
00178 const CSCChamber* chamber = theGeometry->chamber( chamberId );
00179 if ( chamber ){
00180 }
00181 else {
00182
00183 LogTrace(myName) << myName <<": CSCChamberSpecs::build requested for ME" << jstat << jring ;
00184 int chamberType = CSCChamberSpecs::whatChamberType( jstat, jring );
00185 const CSCChamberSpecs* aSpecs = theGeometry->findSpecs( chamberType );
00186
00187
00188
00189 if ( fupar.size() != 0 && aSpecs == 0 ) {
00190
00191 aSpecs = theGeometry->buildSpecs (chamberType, fpar, fupar, wg);
00192 } else if ( fupar.size() == 0 && aSpecs == 0 ) {
00193 std::cout << "SHOULD BE THROW? Error, wg and/or fupar size are 0 BUT this Chamber Spec has not been built!" << std::endl;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 BoundSurface::RotationType aRot( grmat[0], grmat[1], grmat[2],
00208 grmat[3], grmat[4], grmat[5],
00209 grmat[6], grmat[7], grmat[8] );
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 Basic3DVector<float> oldX( 1., 0., 0. );
00225 Basic3DVector<float> oldY( 0., 0., -1. );
00226 Basic3DVector<float> oldZ( 0., 1., 0. );
00227
00228 if ( gtran[2]<0. ) oldX *= -1;
00229
00230 aRot.rotateAxes( oldX, oldY, oldZ );
00231
00232
00233
00234 float frameThickness = fupar[31]/10.;
00235 float gapThickness = fupar[32]/10.;
00236 float panelThickness = fupar[33]/10.;
00237 float zAverageAGVtoAF = fupar[34]/10.;
00238
00239 float layerThickness = gapThickness;
00240 float layerSeparation = gapThickness + panelThickness;
00241
00242 float chamberThickness = 7.*panelThickness + 6.*gapThickness + 2.*frameThickness ;
00243 float hChamberThickness = chamberThickness/2.;
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 TrapezoidalPlaneBounds* bounds = new TrapezoidalPlaneBounds( fpar[0], fpar[1], fpar[3], hChamberThickness );
00264
00265
00266 Surface::PositionType aVec( gtran[0], gtran[1], gtran[2] );
00267
00268 BoundPlane::BoundPlanePointer plane = BoundPlane::build(aVec, aRot, bounds);
00269 delete bounds;
00270
00271 CSCChamber* chamber = new CSCChamber( plane, chamberId, aSpecs );
00272 theGeometry->addChamber( chamber );
00273
00274 LogTrace(myName) << myName << ": Create chamber E" << jend << " S" << jstat
00275 << " R" << jring << " C" << jch
00276 << " z=" << gtran[2]
00277 << " t/2=" << fpar[2] << " (DDD) or " << hChamberThickness
00278 << " (specs) adr=" << chamber ;
00279
00280
00281
00282
00283
00284
00285
00286 int localZwrtGlobalZ = +1;
00287 if ( (jend==1 && jstat<3 ) || ( jend==2 && jstat>2 ) ) localZwrtGlobalZ = -1;
00288 int globalZ = +1;
00289 if ( jend == 2 ) globalZ = -1;
00290
00291
00292
00293
00294 LogTrace(myName) << myName << ": layerSeparation=" << layerSeparation
00295 << ", zAF-zAverageAGV=" << zAverageAGVtoAF
00296 << ", localZwrtGlobalZ=" << localZwrtGlobalZ
00297 << ", gtran[2]=" << gtran[2] ;
00298
00299 for ( short j = 1; j <= 6; ++j ) {
00300
00301 CSCDetId layerId = CSCDetId( jend, jstat, jring, jch, j );
00302
00303
00304 const CSCLayer* cLayer = dynamic_cast<const CSCLayer*> (theGeometry->idToDet( layerId ) );
00305
00306 if ( cLayer == 0 ) {
00307
00308
00309 const CSCChamberSpecs* aSpecs = chamber->specs();
00310 const CSCLayerGeometry* geom =
00311 (j%2 != 0) ? aSpecs->oddLayerGeometry( jend ) :
00312 aSpecs->evenLayerGeometry( jend );
00313
00314
00315
00316
00317 float zlayer = gtran[2] - globalZ*zAverageAGVtoAF + localZwrtGlobalZ*(3.5-j)*layerSeparation;
00318
00319 BoundSurface::RotationType chamberRotation = chamber->surface().rotation();
00320 BoundPlane::PositionType layerPosition( gtran[0], gtran[1], zlayer );
00321 std::array<const float, 4> const & dims = geom->parameters();
00322
00323 TrapezoidalPlaneBounds* bounds = new TrapezoidalPlaneBounds( dims[0], dims[1], dims[3], layerThickness/2. );
00324 BoundPlane::BoundPlanePointer plane = BoundPlane::build(layerPosition, chamberRotation, bounds);
00325 delete bounds;
00326
00327 CSCLayer* layer = new CSCLayer( plane, layerId, chamber, geom );
00328
00329 LogTrace(myName) << myName << ": Create layer E" << jend << " S" << jstat
00330 << " R" << jring << " C" << jch << " L" << j
00331 << " z=" << zlayer
00332 << " t=" << layerThickness << " or " << layer->surface().bounds().thickness()
00333 << " adr=" << layer << " layerGeom adr=" << geom ;
00334
00335 chamber->addComponent(j, layer);
00336 theGeometry->addLayer( layer );
00337 }
00338 else {
00339 edm::LogError(myName) << ": ERROR, layer " << j <<
00340 " for chamber = " << ( chamber->id() ) <<
00341 " already exists: layer address=" << cLayer <<
00342 " chamber address=" << chamber << "\n";
00343 }
00344
00345 }
00346 }
00347 }