00001 #include <DetectorDescription/Core/interface/DDFilter.h>
00002 #include <DetectorDescription/Core/interface/DDFilteredView.h>
00003 #include <DetectorDescription/Core/interface/DDSolid.h>
00004
00005 #include <Geometry/CSCGeometryBuilder/src/CSCGeometryBuilderFromDDD.h>
00006 #include <Geometry/CSCGeometry/interface/CSCGeometry.h>
00007 #include <Geometry/CSCGeometry/interface/CSCChamberSpecs.h>
00008 #include <Geometry/CSCGeometry/interface/CSCChamber.h>
00009 #include <Geometry/CSCGeometry/interface/CSCLayer.h>
00010 #include <Geometry/CSCGeometry/interface/CSCLayerGeometry.h>
00011 #include <Geometry/CSCGeometry/src/CSCWireGroupPackage.h>
00012 #include <Geometry/MuonNumbering/interface/CSCNumberingScheme.h>
00013 #include <Geometry/MuonNumbering/interface/MuonBaseNumber.h>
00014 #include <Geometry/MuonNumbering/interface/MuonDDDNumbering.h>
00015 #include <DataFormats/GeometrySurface/interface/BoundPlane.h>
00016 #include <DataFormats/GeometrySurface/interface/TrapezoidalPlaneBounds.h>
00017 #include <DataFormats/GeometryVector/interface/Basic3DVector.h>
00018
00019 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00020
00021 #include <CLHEP/Units/SystemOfUnits.h>
00022
00023 #include <iostream>
00024 #include <iomanip>
00025
00026 CSCGeometryBuilderFromDDD::CSCGeometryBuilderFromDDD() : myName("CSCGeometryBuilderFromDDD"){}
00027
00028
00029 CSCGeometryBuilderFromDDD::~CSCGeometryBuilderFromDDD(){}
00030
00031
00032 void CSCGeometryBuilderFromDDD::build(boost::shared_ptr<CSCGeometry> geom, const DDCompactView* cview, const MuonDDDConstants& muonConstants){
00033
00034 std::string attribute = "MuStructure";
00035 std::string value = "MuonEndcapCSC";
00036 DDValue muval(attribute, value, 0.0);
00037
00038
00039
00040 DDSpecificsFilter filter;
00041 filter.setCriteria(muval,
00042 DDSpecificsFilter::equals,
00043 DDSpecificsFilter::AND,
00044 true,
00045 true
00046 );
00047
00048 DDFilteredView fview( *cview );
00049 fview.addFilter(filter);
00050
00051 bool doSubDets = fview.firstChild();
00052 doSubDets = fview.firstChild();
00053 buildEndcaps( geom, &fview, muonConstants );
00054
00055 }
00056
00057 void CSCGeometryBuilderFromDDD::buildEndcaps( boost::shared_ptr<CSCGeometry> theGeometry,
00058 DDFilteredView* fv, const MuonDDDConstants& muonConstants ){
00059
00060 bool doAll(true);
00061
00062
00063
00064 int noOfAnonParams = 0;
00065
00066 while (doAll) {
00067 std::string upstr = "upar";
00068 std::vector<const DDsvalues_type *> spec = fv->specifics();
00069 std::vector<const DDsvalues_type *>::const_iterator spit = spec.begin();
00070
00071 std::vector<double> uparvals;
00072
00073
00074 CSCWireGroupPackage wg;
00075
00076
00077 for (; spit != spec.end(); spit++) {
00078 DDsvalues_type::const_iterator it = (**spit).begin();
00079 for (; it != (**spit).end(); it++) {
00080
00081 if (it->second.name() == upstr) {
00082 uparvals = it->second.doubles();
00083
00084 } else if (it->second.name() == "NoOfAnonParams") {
00085 noOfAnonParams = static_cast<int>( it->second.doubles()[0] );
00086 } else if (it->second.name() == "NumWiresPerGrp") {
00087
00088 for ( size_t i = 0 ; i < it->second.doubles().size(); i++) {
00089 wg.wiresInEachGroup.push_back( int( it->second.doubles()[i] ) );
00090 }
00091
00092 } else if ( it->second.name() == "NumGroups" ) {
00093
00094 for ( size_t i = 0 ; i < it->second.doubles().size(); i++) {
00095 wg.consecutiveGroups.push_back( int( it->second.doubles()[i] ) );
00096 }
00097 } else if ( it->second.name() == "WireSpacing" ) {
00098 wg.wireSpacing = it->second.doubles()[0];
00099 } else if ( it->second.name() == "AlignmentPinToFirstWire" ) {
00100 wg.alignmentPinToFirstWire = it->second.doubles()[0];
00101 } else if ( it->second.name() == "TotNumWireGroups" ) {
00102 wg.numberOfGroups = int(it->second.doubles()[0]);
00103 } else if ( it->second.name() == "LengthOfFirstWire" ) {
00104 wg.narrowWidthOfWirePlane = it->second.doubles()[0];
00105 } else if ( it->second.name() == "LengthOfLastWire" ) {
00106 wg.wideWidthOfWirePlane = it->second.doubles()[0];
00107 } else if ( it->second.name() == "RadialExtentOfWirePlane" ) {
00108 wg.lengthOfWirePlane = it->second.doubles()[0];
00109 }
00110 }
00111 }
00112
00113 std::vector<float> fpar;
00114 std::vector<double> dpar;
00115 if ( fv->logicalPart().solid().shape() == ddsubtraction ) {
00116 const DDSubtraction& first = fv->logicalPart().solid();
00117 const DDSubtraction& second = first.solidA();
00118 const DDSolid& third = second.solidA();
00119 dpar = third.parameters();
00120 } else {
00121 dpar = fv->logicalPart().solid().parameters();
00122 }
00123
00124 LogTrace(myName) << myName << ": noOfAnonParams=" << noOfAnonParams;
00125
00126 LogTrace(myName) << myName << ": fill fpar...";
00127 LogTrace(myName) << myName << ": dpars are... " <<
00128 dpar[4]/cm << ", " << dpar[8]/cm << ", " <<
00129 dpar[3]/cm << ", " << dpar[0]/cm;
00130
00131
00132 fpar.push_back( static_cast<float>( dpar[4]/cm) );
00133 fpar.push_back( static_cast<float>( dpar[8]/cm ) );
00134 fpar.push_back( static_cast<float>( dpar[3]/cm ) );
00135 fpar.push_back( static_cast<float>( dpar[0]/cm ) );
00136
00137 LogTrace(myName) << myName << ": fill gtran...";
00138
00139 std::vector<float> gtran( 3 );
00140
00141 gtran[0] = (float) 1.0 * (fv->translation().X() / cm);
00142 gtran[1] = (float) 1.0 * (fv->translation().Y() / cm);
00143 gtran[2] = (float) 1.0 * (fv->translation().Z() / cm);
00144
00145 LogTrace(myName) << myName << ": gtran[0]=" << gtran[0] << ", gtran[1]=" <<
00146 gtran[1] << ", gtran[2]=" << gtran[2];
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 LogTrace(myName) << myName << ": fill grmat...";
00157
00158 std::vector<float> grmat( 9 );
00159
00160 std::vector<float> trm(9);
00161 fv->rotation().GetComponents(trm.begin(), trm.end());
00162 size_t rotindex = 0;
00163 for (size_t i = 0; i < 9; ++i) {
00164 grmat[i] = (float) 1.0 * trm[rotindex];
00165 rotindex = rotindex + 3;
00166 if ( (i+1) % 3 == 0 ) {
00167 rotindex = (i+1) / 3;
00168 }
00169 }
00170
00171 LogTrace(myName) << myName << ": fill fupar...";
00172
00173 std::vector<float> fupar;
00174 for (size_t i = 0; i < uparvals.size(); i++)
00175 fupar.push_back( static_cast<float>( uparvals[i] ) );
00176
00177
00178
00179 LogTrace(myName) << myName << ": create numbering scheme...";
00180
00181 MuonDDDNumbering mdn(muonConstants);
00182 MuonBaseNumber mbn = mdn.geoHistoryToBaseNumber(fv->geoHistory());
00183 CSCNumberingScheme mens(muonConstants);
00184
00185 LogTrace(myName) << myName << ": find detid...";
00186
00187 int id = mens.baseNumberToUnitNumber( mbn );
00188
00189 LogTrace(myName) << myName << ": raw id for this detector is " << id <<
00190 ", octal " << std::oct << id << ", hex " << std::hex << id << std::dec;
00191 LogTrace(myName) << myName << ": looking for wire group info for layer " <<
00192 "E" << CSCDetId::endcap(id) <<
00193 " S" << CSCDetId::station(id) <<
00194 " R" << CSCDetId::ring(id) <<
00195 " C" << CSCDetId::chamber(id) <<
00196 " L" << CSCDetId::layer(id);
00197
00198 if ( wg.numberOfGroups != 0 ) {
00199 LogTrace(myName) << myName << ": fv->geoHistory: = " << fv->geoHistory() ;
00200 LogTrace(myName) << myName << ": TotNumWireGroups = " << wg.numberOfGroups ;
00201 LogTrace(myName) << myName << ": WireSpacing = " << wg.wireSpacing ;
00202 LogTrace(myName) << myName << ": AlignmentPinToFirstWire = " << wg.alignmentPinToFirstWire ;
00203 LogTrace(myName) << myName << ": Narrow width of wire plane = " << wg.narrowWidthOfWirePlane ;
00204 LogTrace(myName) << myName << ": Wide width of wire plane = " << wg.wideWidthOfWirePlane ;
00205 LogTrace(myName) << myName << ": Length in y of wire plane = " << wg.lengthOfWirePlane ;
00206 LogTrace(myName) << myName << ": wg.consecutiveGroups.size() = " << wg.consecutiveGroups.size() ;
00207 LogTrace(myName) << myName << ": wg.wiresInEachGroup.size() = " << wg.wiresInEachGroup.size() ;
00208 LogTrace(myName) << myName << ": \tNumGroups\tWiresInGroup" ;
00209 for (size_t i = 0; i < wg.consecutiveGroups.size(); i++) {
00210 LogTrace(myName) << myName << " \t" << wg.consecutiveGroups[i] << "\t\t" << wg.wiresInEachGroup[i] ;
00211 }
00212 } else {
00213 LogTrace(myName) << myName << ": missing specpars for wire groups" ;
00214 }
00215 LogTrace(myName) << myName << ": end of wire group info. " ;
00216
00217 CSCDetId detid = CSCDetId( id );
00218 int jendcap = detid.endcap();
00219 int jstation = detid.station();
00220 int jring = detid.ring();
00221 int jchamber = detid.chamber();
00222 int jlayer = detid.layer();
00223
00224 LogTrace(myName) << myName << ":_z_ E" << jendcap << " S" << jstation << " R" << jring <<
00225 " C" << jchamber << " L" << jlayer <<
00226 " gx=" << gtran[0] << ", gy=" << gtran[1] << ", gz=" << gtran[2] <<
00227 " thickness=" << fpar[2]*2.;
00228
00229 if ( jlayer == 0 ) {
00230
00231 LogTrace(myName) << myName << ":_z_ frame=" << fupar[31]/10. <<
00232 " gap=" << fupar[32]/10. << " panel=" << fupar[33]/10. << " offset=" << fupar[34]/10.;
00233
00234
00235 if ( !theGeometry->centreTIOffsets() ) fupar[30] = 0.;
00236
00237 if ( jstation==1 && jring==1 ) {
00238
00239
00240
00241
00242 buildChamber (theGeometry, detid, fpar, fupar, gtran, grmat, wg );
00243
00244
00245
00246
00247
00248 const int kNoOfAnonParams = 35;
00249 if ( noOfAnonParams == 0 ) { noOfAnonParams = kNoOfAnonParams; }
00250
00251 std::copy( fupar.begin()+noOfAnonParams, fupar.end(), fupar.begin() );
00252 CSCDetId detid1a = CSCDetId( jendcap, 1, 4, jchamber, 0 );
00253 buildChamber (theGeometry, detid1a, fpar, fupar, gtran, grmat, wg );
00254
00255 }
00256 else {
00257 buildChamber (theGeometry, detid, fpar, fupar, gtran, grmat, wg );
00258 }
00259
00260 }
00261
00262 doAll = fv->next();
00263 }
00264
00265 }
00266
00267 void CSCGeometryBuilderFromDDD::buildChamber (
00268 boost::shared_ptr<CSCGeometry> theGeometry,
00269 CSCDetId chamberId,
00270 const std::vector<float>& fpar,
00271 const std::vector<float>& fupar,
00272 const std::vector<float>& gtran,
00273 const std::vector<float>& grmat,
00274 const CSCWireGroupPackage& wg
00275 ) {
00276
00277 LogTrace(myName) << myName << ": entering buildChamber" ;
00278
00279 int jend = chamberId.endcap();
00280 int jstat = chamberId.station();
00281 int jring = chamberId.ring();
00282 int jch = chamberId.chamber();
00283 int jlay = chamberId.layer();
00284
00285 if (jlay != 0 ) edm::LogWarning(myName) << "Error! CSCGeometryBuilderFromDDD was fed layer id = " << jlay << "\n";
00286
00287 const size_t kNpar = 4;
00288 if ( fpar.size() != kNpar )
00289 edm::LogError(myName) << "Error, expected npar="
00290 << kNpar << ", found npar=" << fpar.size() << std::endl;
00291
00292 LogTrace(myName) << myName << ": E" << jend << " S" << jstat << " R" << jring <<
00293 " C" << jch << " L" << jlay ;
00294 LogTrace(myName) << myName << ": npar=" << fpar.size() << " hB=" << fpar[0]
00295 << " hT=" << fpar[1] << " hD=" << fpar[2] << " hH=" << fpar[3] ;
00296 LogTrace(myName) << myName << ": gtran[0,1,2]=" << gtran[0] << " " << gtran[1] << " " << gtran[2] ;
00297 LogTrace(myName) << myName << ": grmat[0-8]=" << grmat[0] << " " << grmat[1] << " " << grmat[2] << " "
00298 << grmat[3] << " " << grmat[4] << " " << grmat[5] << " "
00299 << grmat[6] << " " << grmat[7] << " " << grmat[8] ;
00300 LogTrace(myName) << myName << ": nupar=" << fupar.size() << " upar[0]=" << fupar[0]
00301 << " upar[" << fupar.size()-1 << "]=" << fupar[fupar.size()-1];
00302
00303
00304 CSCChamber* chamber = const_cast<CSCChamber*>(theGeometry->chamber( chamberId ));
00305 if ( chamber ){
00306 }
00307 else {
00308
00309 LogTrace(myName) << myName <<": buildSpecs requested for ME" << jstat << jring ;
00310 int chamberType = CSCChamberSpecs::whatChamberType( jstat, jring );
00311 const CSCChamberSpecs* aSpecs = theGeometry->findSpecs( chamberType );
00312 if ( aSpecs == 0 ) aSpecs = theGeometry->buildSpecs( chamberType, fpar, fupar, wg );
00313
00314
00315
00316
00317
00318
00319
00320
00321 BoundSurface::RotationType aRot( grmat[0], grmat[1], grmat[2],
00322 grmat[3], grmat[4], grmat[5],
00323 grmat[6], grmat[7], grmat[8] );
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 Basic3DVector<float> oldX( 1., 0., 0. );
00339 Basic3DVector<float> oldY( 0., 0., -1. );
00340 Basic3DVector<float> oldZ( 0., 1., 0. );
00341
00342 if ( gtran[2]<0. ) oldX *= -1;
00343
00344 aRot.rotateAxes( oldX, oldY, oldZ );
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 float frameThickness = fupar[31]/10.;
00355 float gapThickness = fupar[32]/10.;
00356 float panelThickness = fupar[33]/10.;
00357 float zAverageAGVtoAF = fupar[34]/10.;
00358
00359 float layerThickness = gapThickness;
00360 float layerSeparation = gapThickness + panelThickness;
00361
00362 float chamberThickness = 7.*panelThickness + 6.*gapThickness + 2.*frameThickness ;
00363 float hChamberThickness = chamberThickness/2.;
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 TrapezoidalPlaneBounds* bounds = new TrapezoidalPlaneBounds( fpar[0], fpar[1], fpar[3], hChamberThickness );
00384
00385
00386 Surface::PositionType aVec( gtran[0], gtran[1], gtran[2] );
00387
00388 BoundPlane::BoundPlanePointer plane = BoundPlane::build(aVec, aRot, bounds);
00389 delete bounds;
00390
00391 CSCChamber* chamber = new CSCChamber( plane, chamberId, aSpecs );
00392 theGeometry->addChamber( chamber );
00393
00394 LogTrace(myName) << myName << ": Create chamber E" << jend << " S" << jstat
00395 << " R" << jring << " C" << jch
00396 << " z=" << gtran[2]
00397 << " t/2=" << fpar[2] << " (DDD) or " << hChamberThickness
00398 << " (specs) adr=" << chamber ;
00399
00400
00401
00402
00403
00404
00405
00406 int localZwrtGlobalZ = +1;
00407 if ( (jend==1 && jstat<3 ) || ( jend==2 && jstat>2 ) ) localZwrtGlobalZ = -1;
00408 int globalZ = +1;
00409 if ( jend == 2 ) globalZ = -1;
00410
00411 LogTrace(myName) << myName << ": layerSeparation=" << layerSeparation
00412 << ", zAF-zAverageAGV=" << zAverageAGVtoAF
00413 << ", localZwrtGlobalZ=" << localZwrtGlobalZ
00414 << ", gtran[2]=" << gtran[2] ;
00415
00416 for ( short j = 1; j <= 6; ++j ) {
00417
00418 CSCDetId layerId = CSCDetId( jend, jstat, jring, jch, j );
00419
00420
00421 const CSCLayer* cLayer = dynamic_cast<const CSCLayer*> (theGeometry->idToDet( layerId ) );
00422
00423 if ( cLayer == 0 ) {
00424
00425
00426 const CSCChamberSpecs* aSpecs = chamber->specs();
00427 const CSCLayerGeometry* geom =
00428 (j%2 != 0) ? aSpecs->oddLayerGeometry( jend ) :
00429 aSpecs->evenLayerGeometry( jend );
00430
00431
00432
00433
00434
00435 float zlayer = gtran[2] - globalZ*zAverageAGVtoAF + localZwrtGlobalZ*(3.5-j)*layerSeparation;
00436
00437 BoundSurface::RotationType chamberRotation = chamber->surface().rotation();
00438 BoundPlane::PositionType layerPosition( gtran[0], gtran[1], zlayer );
00439
00440
00441 std::vector<float> dims = geom->parameters();
00442 dims[2] = layerThickness/2.;
00443
00444
00445 TrapezoidalPlaneBounds* bounds = new TrapezoidalPlaneBounds( dims[0], dims[1], dims[3], dims[2] );
00446 BoundPlane::BoundPlanePointer plane = BoundPlane::build(layerPosition, chamberRotation, bounds);
00447 delete bounds;
00448
00449 CSCLayer* layer = new CSCLayer( plane, layerId, chamber, geom );
00450
00451 LogTrace(myName) << myName << ": Create layer E" << jend << " S" << jstat
00452 << " R" << jring << " C" << jch << " L" << j
00453 << " z=" << zlayer
00454 << " t=" << layerThickness << " or " << layer->surface().bounds().thickness()
00455 << " adr=" << layer << " layerGeom adr=" << geom ;
00456
00457 chamber->addComponent(j, layer);
00458 theGeometry->addLayer( layer );
00459 }
00460 else {
00461 edm::LogError(myName) << ": ERROR, layer " << j <<
00462 " for chamber = " << ( chamber->id() ) <<
00463 " already exists: layer address=" << cLayer <<
00464 " chamber address=" << chamber << "\n";
00465 }
00466
00467 }
00468 }
00469 }
00470
00471
00472