CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DetectorDescription/Parser/src/DDDividedPolyhedra.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // 25.04.04 - M. Case ddd-ize G4ParameterisationPolyhedra*
00004 //---------------------------------------------------------------------
00005 #include "DetectorDescription/Parser/src/DDDividedPolyhedra.h"
00006 #include "DetectorDescription/Parser/src/DDXMLElement.h"
00007 
00008 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
00009 #include "DetectorDescription/Core/interface/DDName.h"
00010 #include "DetectorDescription/Core/interface/DDSolid.h"
00011 #include "DetectorDescription/Core/interface/DDMaterial.h"
00012 
00013 #include "DetectorDescription/Base/interface/DDdebug.h"
00014 #include "DetectorDescription/Base/interface/DDException.h"
00015 #include "DetectorDescription/Base/interface/DDRotationMatrix.h"
00016 
00017 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00018 
00019 DDDividedPolyhedraRho::DDDividedPolyhedraRho( const DDDivision& div, DDCompactView* cpv )
00020   : DDDividedGeometryObject( div, cpv )
00021 {
00022   checkParametersValidity();
00023   setType( "DivisionPolyhedraRho" );
00024 
00025   DDPolyhedra msol = (DDPolyhedra)( div_.parent().solid() );
00026 
00027   if( divisionType_ == DivWIDTH )
00028   {
00029     compNDiv_ = calculateNDiv( msol.rMaxVec()[0] - msol.rMinVec()[0]
00030                                , div_.width()
00031                                , div_.offset() );
00032   }
00033   else if( divisionType_ == DivNDIV )
00034   {
00035     compWidth_ = calculateWidth( msol.rMaxVec()[0] - msol.rMinVec()[0]
00036                                  , div_.nReplicas()
00037                                  , div_.offset() );
00038   }
00039 
00040   //     for (int i = 0; i < compNDiv_; ++i)
00041   //      {
00042   //        DDpos(  makeDDLogicalPart(i)
00043   //          , div_.parent()
00044   //          , i
00045   //          , makeDDTranslation(i)
00046   //          , makeDDRotation(i)
00047   //          , &div_
00048   //          );
00049   //      } 
00050  
00051   DCOUT_V ('P', " DDDividedPolyhedraRho - # divisions " << compNDiv_  << " = " << div_.nReplicas() << "\n Offset " << div_.offset() << " Width " << compWidth_ << " = " << div_.width() << "\n");
00052 
00053 }
00054 
00055 DDDividedPolyhedraRho::~DDDividedPolyhedraRho( void )
00056 {}
00057 
00058 void
00059 DDDividedPolyhedraRho::checkParametersValidity( void )
00060 {
00061   DDDividedGeometryObject::checkParametersValidity();
00062 
00063   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00064 
00065   if( divisionType_ == DivNDIVandWIDTH || divisionType_ == DivWIDTH )
00066   {
00067     std::cout << "WARNING - "
00068               << "DDDividedPolyhedraRho::checkParametersValidity()"
00069               << std::endl
00070               << "          Solid " << msol << std::endl
00071               << "          Division along R will be done with a width "
00072               << "different for each solid section." << std::endl
00073               << "          WIDTH will not be used !" << std::endl;
00074   }
00075   if( div_.offset() != 0. )
00076   {
00077     std::cout << "WARNING - "
00078               << "DDDividedPolyhedraRho::checkParametersValidity()"
00079               << std::endl
00080               << "          Solid " << msol << std::endl
00081               << "          Division along  R will be done with a width "
00082               << "different for each solid section." << std::endl
00083               << "          OFFSET will not be used !" << std::endl;
00084   }
00085 }
00086 
00087 double
00088 DDDividedPolyhedraRho::getMaxParameter( void ) const
00089 {
00090   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00091   return msol.rMaxVec()[0] - msol.rMinVec()[0];
00092 }
00093 
00094 DDTranslation
00095 DDDividedPolyhedraRho::makeDDTranslation( const int copyNo ) const
00096 {
00097   return DDTranslation();
00098 }
00099 
00100 DDRotation
00101 DDDividedPolyhedraRho::makeDDRotation( const int copyNo ) const
00102 {
00103   return DDRotation();
00104 }
00105 
00106 DDLogicalPart
00107 DDDividedPolyhedraRho::makeDDLogicalPart( const int copyNo ) const
00108 {
00109   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00110   DDMaterial usemat = div_.parent().material();
00111 
00112   std::vector<double> localrMaxVec = msol.rMaxVec();
00113   std::vector<double> localrMinVec = msol.rMinVec();
00114   std::vector<double> localzVec = msol.zVec(); 
00115   std::vector<double> newrMinVec;
00116   std::vector<double> newrMaxVec;
00117   int nZplanes = localzVec.size();
00118 
00119   double width = 0.;
00120   for(int ii = 0; ii < nZplanes; ++ii)
00121   {
00122     //     width = CalculateWidth( origparamMother->Rmax[ii]
00123     //                           - origparamMother->Rmin[ii], compNDiv_, foffset );
00124     //     origparam.Rmin[ii] = origparamMother->Rmin[ii]+foffset+width*copyNo;
00125     //     origparam.Rmax[ii] = origparamMother->Rmin[ii]+foffset+width*(copyNo+1);
00126     width = calculateWidth(localrMaxVec[ii] - localrMinVec[ii], compNDiv_, div_.offset());
00127     newrMinVec[ii] = localrMinVec[ii] + div_.offset() + width * copyNo;
00128     newrMaxVec[ii] = localrMaxVec[ii] + div_.offset() + width * (copyNo + 1);
00129   }
00130 
00131   //   phedra.SetOriginalParameters(&origparam); // copy values & transfer pointers
00132   //   phedra.Reset();                           // reset to new solid parameters
00133   
00134   DDName solname(div_.parent().ddname().name() + "_DIVCHILD" + DDXMLElement::itostr(copyNo) 
00135                  , div_.parent().ddname().ns());
00136   
00137   DDSolid dsol = DDSolidFactory::polyhedra(solname
00138                                            , msol.sides()
00139                                            , msol.startPhi()
00140                                            , msol.deltaPhi()
00141                                            , localzVec
00142                                            , newrMinVec
00143                                            , newrMaxVec);
00144   DDLogicalPart ddlp = DDLogicalPart(solname, usemat, dsol);
00145   DCOUT_V ('P', "DDDividedPolyhedraRho:makeDDLogicalPart lp:" <<  ddlp);
00146   return ddlp;
00147 }
00148 
00149 DDDividedPolyhedraPhi::DDDividedPolyhedraPhi( const DDDivision& div, DDCompactView* cpv )
00150   : DDDividedGeometryObject( div, cpv )
00151 { 
00152   checkParametersValidity();
00153   setType( "DivisionPolyhedraPhi" );
00154 
00155   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00156   //  double deltaPhi = msol->GetEndPhi() - msol->GetStartPhi();
00157   
00158   if( divisionType_ == DivWIDTH )
00159   {
00160     //If you divide a tube of 360 degrees the offset displaces the starting angle, but you still fill the 360 degrees
00161     if( msol.deltaPhi() == 360.*deg ) {
00162       compNDiv_ = calculateNDiv( msol.deltaPhi(), div_.width(), 0. );
00163     }else {
00164       compNDiv_ = calculateNDiv( msol.deltaPhi(), div_.width(), div_.offset() );
00165     }
00166   }
00167   else if( divisionType_ == DivNDIV )
00168   {
00169     if( msol.deltaPhi() == 360.*deg ) {
00170       compWidth_ = calculateWidth( msol.deltaPhi(), div_.nReplicas(), 0. );
00171     }else {
00172       // original line looks wrong!
00173       compWidth_ = calculateWidth( msol.deltaPhi(), div_.nReplicas(), div_.offset() );
00174     }
00175   }
00176  
00177   DCOUT_V ('P', " DDDividedPolyhedraRho - # divisions " << compNDiv_  << " = " << div_.nReplicas() << "\n Offset " << div_.offset() << " Width " << compWidth_ << " = " << div_.width() << "\n");
00178 }
00179 
00180 DDDividedPolyhedraPhi::~DDDividedPolyhedraPhi( void )
00181 {}
00182 
00183 double
00184 DDDividedPolyhedraPhi::getMaxParameter( void ) const
00185 {
00186   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00187   return msol.deltaPhi(); //msol->GetEndPhi() - msol->GetStartPhi();
00188 }
00189 
00190 void
00191 DDDividedPolyhedraPhi::checkParametersValidity( void )
00192 {
00193   DDDividedGeometryObject::checkParametersValidity();
00194   
00195   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00196   
00197   if( divisionType_ == DivNDIVandWIDTH || divisionType_ == DivWIDTH )
00198   {
00199     std::cout << "WARNING - "
00200               << "DDDividedPolyhedraPhi::checkParametersValidity()"
00201               << std::endl
00202               << "          Solid " << msol << std::endl
00203               << "          Division along PHI will be done splitting "
00204               << "in the defined numSide." << std::endl
00205               << "          WIDTH will not be used !" << std::endl;
00206   }
00207   if( div_.offset() != 0. )
00208   {
00209     std::cout << "WARNING - "
00210               << "DDDividedPolyhedraPhi::checkParametersValidity()"
00211               << std::endl
00212               << "          Solid " << msol << std::endl
00213               << "          Division along PHI will be done splitting "
00214               << "in the defined numSide." << std::endl
00215               << "          OFFSET will not be used !" << std::endl;
00216   }
00217   
00218   if ( msol.sides() != compNDiv_ )
00219   { 
00220     std::cout << "ERROR - "
00221               << "DDDividedPolyhedraPhi::checkParametersValidity()"
00222               << std::endl
00223               << "        Division along PHI will be done splitting in the defined"
00224               << std::endl
00225               << "        numSide, i.e, the number of division would be :"
00226               << "        " << msol.sides()
00227               << " instead of " << compNDiv_ << " !"
00228               << std::endl; 
00229     std::string s = "DDDividedPolyhedraPhi::checkParametersValidity() Not supported configuration.";
00230     throw DDException(s);
00231   }
00232 }
00233 
00234 DDTranslation
00235 DDDividedPolyhedraPhi::makeDDTranslation( const int copyNo ) const
00236 {
00237   return DDTranslation();
00238 }
00239 
00240 DDRotation
00241 DDDividedPolyhedraPhi::makeDDRotation( const int copyNo ) const
00242 {
00243 
00244   double posi = ( copyNo - 1 ) * compWidth_;
00245 
00246   DCOUT_V ('P', " DDDividedPolyhedraPhi - position: " << posi/deg << "\n copyNo: " << copyNo << " - compWidth_: " << compWidth_/deg << "\n");
00247   
00248   //  ChangeRotMatrix( physVol, -posi );
00249   DDRotationMatrix* rotMat = changeRotMatrix( posi);
00250   // how to name the rotation??
00251   // i do not like this...
00252   DDName ddrotname(div_.parent().ddname().name() + "_DIVCHILD_ROT" + DDXMLElement::itostr(copyNo)
00253                    , div_.parent().ddname().ns());
00254   DDRotation myddrot = DDrot(ddrotname, rotMat);
00255   DCOUT_V ('P', "DDDividedPolyhedra::makeDDRotation: copyNo = " << copyNo << " rotation = " << myddrot);
00256   return myddrot;
00257 
00258 }
00259 
00260 DDLogicalPart
00261 DDDividedPolyhedraPhi::makeDDLogicalPart( const int copyNo ) const
00262 {
00263   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00264   DDMaterial usemat = div_.parent().material();
00265 
00266   DDName solname( div_.parent().ddname().name() + "_DIVCHILD",
00267                   div_.parent().ddname().ns());
00268   DDSolid dsol(solname);
00269   if (!dsol.isDefined().second)
00270   {
00271     dsol = DDSolidFactory::polyhedra( solname,
00272                                       msol.sides(),
00273                                       msol.startPhi()+div_.offset(),
00274                                       compWidth_,
00275                                       msol.zVec(),
00276                                       msol.rMinVec(),
00277                                       msol.rMaxVec());
00278   }
00279   DDLogicalPart ddlp(solname);
00280   if (!ddlp.isDefined().second)
00281     DDLogicalPart ddlp2 = DDLogicalPart(solname, usemat, dsol);
00282   DCOUT_V ('P', "DDDividedPolyhedraPhi::makeDDLogicalPart() ddlp = " << ddlp);
00283   return ddlp;
00284 }
00285 
00286 DDDividedPolyhedraZ::DDDividedPolyhedraZ( const DDDivision& div, DDCompactView* cpv )
00287   : DDDividedGeometryObject( div, cpv )
00288 { 
00289   checkParametersValidity();
00290   setType( "DivisionPolyhedraZ" );
00291   
00292   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00293 
00294   std::vector<double> zvec = msol.zVec();
00295   
00296   if  ( divisionType_ == DivWIDTH )
00297   {
00298     compNDiv_ =
00299       calculateNDiv( zvec[zvec.size() - 1] - zvec[0], div_.width(), div_.offset() );
00300   }
00301   else if( divisionType_ == DivNDIV )
00302   {
00303     compWidth_ = calculateWidth( zvec[zvec.size() - 1] - zvec[0],
00304                                  div_.nReplicas(),
00305                                  div_.offset());
00306     // ?what?      CalculateNDiv( zvec[zvec.size() - 1] - zvec[0], origparamMother->Z_values[origparamMother->Num_z_planes-1]
00307     //       - origparamMother->Z_values[0] , nDiv, offset );
00308   }
00309   
00310   DCOUT_V ('P', " DDDividedPolyhedraZ - # divisions " << compNDiv_ << " = " << div_.nReplicas() << "\n Offset " << " = " << div_.offset() << "\n Width " << compWidth_ << " = " << div_.width());
00311 }
00312                                            
00313 DDDividedPolyhedraZ::~DDDividedPolyhedraZ( void )
00314 {}
00315 
00316 double
00317 DDDividedPolyhedraZ::getMaxParameter( void ) const
00318 {
00319   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00320 
00321   std::vector<double> zvec = msol.zVec();
00322   return (zvec[zvec.size() - 1] - zvec[0]);
00323 }
00324 
00325 void
00326 DDDividedPolyhedraZ::checkParametersValidity( void )
00327 {
00328   DDDividedGeometryObject::checkParametersValidity();
00329 
00330   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00331 
00332   if( divisionType_ == DivNDIVandWIDTH || divisionType_ == DivWIDTH )
00333   {
00334     std::cout << "WARNING - "
00335               << "DDDividedPolyhedraZ::checkParametersValidity()"
00336               << std::endl
00337               << "          Solid " << msol << std::endl
00338               << "          Division along Z will be done splitting "
00339               << "in the defined z_planes." << std::endl
00340               << "          WIDTH will not be used !" << std::endl;
00341   }
00342 
00343   if( div_.offset() != 0. )
00344   {
00345     std::cout << "WARNING - "
00346               << "DDDividedPolyhedraZ::checkParametersValidity()"
00347               << std::endl
00348               << "          Solid " << msol << std::endl
00349               << "          Division along Z will be done splitting "
00350               << "in the defined z_planes." << std::endl
00351               << "          OFFSET will not be used !" << std::endl;
00352   }
00353 
00354   std::vector<double> zvec = msol.zVec();
00355   
00356   if ( zvec.size() - 1 != size_t(compNDiv_) )
00357   { 
00358     std::cout << "ERROR - "
00359               << "DDDividedPolyhedraZ::checkParametersValidity()"
00360               << std::endl
00361               << "        Division along Z can only be done by splitting in the defined"
00362               << std::endl
00363               << "        z_planes, i.e, the number of division would be :"
00364               << "        " << zvec.size() - 1
00365               << " instead of " << compNDiv_ << " !"
00366               << std::endl; 
00367     std::string s = "DDDividedPolyhedraZ::checkParametersValidity()";
00368     s += "Illegal Construct. Not a supported configuration.";
00369     throw DDException (s);
00370   }
00371 }
00372 
00373 DDTranslation
00374 DDDividedPolyhedraZ::makeDDTranslation( const int copyNo ) const
00375 {
00376   DDPolyhedra msol = (DDPolyhedra)(div_.parent().solid());
00377   std::vector<double> zvec = msol.zVec();
00378   
00379   //----- set translation: along Z axis
00380   double posi = (zvec[copyNo] + zvec[copyNo+1])/2;
00381   
00382   DDTranslation tr(0,0,posi);
00383   //----- calculate rotation matrix: unit
00384   
00385   DCOUT_V ('P', " DDDividedPolyhedraZ - position: " << posi << "\n copyNo: " << copyNo << " - offset: " << div_.offset()/deg << " - compWidth_: " << compWidth_/deg << " translation = " << tr);
00386   return tr;
00387 }
00388 
00389 DDRotation
00390 DDDividedPolyhedraZ::makeDDRotation( const int copyNo ) const
00391 {
00392   return DDRotation();
00393 }
00394 
00395 DDLogicalPart
00396 DDDividedPolyhedraZ::makeDDLogicalPart( const int copyNo ) const
00397 {
00398   // only for mother number of planes = 2!!
00399   // mec: what?  why?  comment above and = 2 below straight from G4 impl.
00400   DDPolyhedra msol = (DDPolyhedra)( div_.parent().solid());
00401   DDMaterial usemat = div_.parent().material();
00402 
00403   std::vector<double> zvec = msol.zVec();
00404   std::vector<double> rminvec = msol.rMinVec();
00405   std::vector<double> rmaxvec = msol.rMaxVec();
00406 
00407   double posi = ( zvec[ copyNo ] + zvec[ copyNo + 1 ] ) / 2.0;
00408   
00409   DDName solname( div_.parent().ddname().name() + "_DIVCHILD" + DDXMLElement::itostr( copyNo ),
00410                   div_.parent().ddname().ns());
00411   std::vector<double> newRmin, newRmax, newZ;
00412   newZ.push_back( zvec[ copyNo ] - posi );
00413   newZ.push_back( zvec[ copyNo + 1 ] - posi );
00414   newRmin.push_back( rminvec[ copyNo ]);
00415   newRmin.push_back( rminvec[ copyNo + 1 ]);
00416   newRmax.push_back( rmaxvec[ copyNo ]);
00417   newRmax.push_back( rmaxvec[ copyNo + 1 ]);
00418 
00419   DDSolid dsol = DDSolidFactory::polyhedra( solname,
00420                                             msol.sides(),
00421                                             msol.startPhi(),
00422                                             msol.deltaPhi(),
00423                                             newZ,
00424                                             newRmin,
00425                                             newRmax );
00426   DDLogicalPart lp( solname, usemat, dsol );
00427 
00428   DCOUT_V( 'P', "DDDividedPolyhedraZ::makeDDLogicalPart" << "\n-- Parametrised phedra copy-number: " << copyNo << "\n-- DDLogicalPart " << lp );
00429   return lp;
00430 }
00431