CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/SimG4Core/Geometry/src/DDG4Builder.cc

Go to the documentation of this file.
00001 #include "DetectorDescription/Core/interface/DDSpecifics.h"
00002 
00003 #include "FWCore/Utilities/interface/Exception.h"
00004 
00005 #include "SimG4Core/Geometry/interface/DDG4Builder.h"
00006 #include "SimG4Core/Geometry/interface/DDG4SolidConverter.h"
00007 #include "SimG4Core/Geometry/interface/DDG4SensitiveConverter.h"
00008 #include "SimG4Core/Notification/interface/SimG4Exception.h"
00009 #include "DetectorDescription/Core/interface/DDCompactView.h"
00010 
00011 #include "G4VSolid.hh"
00012 #include "G4Box.hh"
00013 #include "G4Tubs.hh"
00014 #include "G4Cons.hh"
00015 #include "G4Trap.hh"
00016 #include "G4Material.hh"
00017 #include "G4LogicalVolume.hh"
00018 #include "G4VPhysicalVolume.hh"
00019 #include "G4PVPlacement.hh"
00020 #include "G4ReflectionFactory.hh"
00021 
00022 #include "G4UnitsTable.hh"
00023 
00024 #include <sstream>
00025 
00026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00027 
00028 DDG4DispContainer * DDG4Builder::theVectorOfDDG4Dispatchables_ = 0;
00029 
00030 DDG4DispContainer * DDG4Builder::theVectorOfDDG4Dispatchables() { 
00031   return theVectorOfDDG4Dispatchables_; 
00032 }
00033 
00034 DDG4Builder::DDG4Builder(const DDCompactView* cpv, bool check) : 
00035   solidConverter_(new DDG4SolidConverter), compactView(cpv), check_(check) { 
00036   theVectorOfDDG4Dispatchables_ = new DDG4DispContainer(); 
00037 }
00038 
00039 DDG4Builder::~DDG4Builder() { 
00040   delete solidConverter_; 
00041 }
00042 
00043 G4LogicalVolume * DDG4Builder::convertLV(const DDLogicalPart & part) {
00044   LogDebug("SimG4CoreGeometry") << "DDG4Builder::convertLV(): DDLogicalPart = " << part;
00045   G4LogicalVolume * result = logs_[part];
00046   if (!result) {
00047     G4VSolid * s   = convertSolid(part.solid());
00048     G4Material * m = convertMaterial(part.material());
00049     result = new G4LogicalVolume(s,m,part.name().name());
00050     map_.insert(result,part);
00051     DDG4Dispatchable * disp = new DDG4Dispatchable(&part,result);       
00052     theVectorOfDDG4Dispatchables_->push_back(disp);
00053     LogDebug("SimG4CoreGeometry") << "DDG4Builder::convertLV(): new G4LogicalVolume " << part.name().name()
00054                                   << "\nDDG4Builder: newEvent: dd=" << part.ddname() << " g4=" << result->GetName();
00055     logs_[part] = result;  // DDD -> GEANT4  
00056   }
00057   return result;
00058 }
00059 
00060 G4VSolid * DDG4Builder::convertSolid(const DDSolid & solid) {
00061   G4VSolid * result = sols_[solid];
00062   if (!result) { 
00063     result = solidConverter_->convert(solid); sols_[solid] = result; 
00064   }
00065   return result;
00066 }
00067 
00068 G4Material * DDG4Builder::convertMaterial(const DDMaterial & material) {
00069   LogDebug("SimG4CoreGeometry") << "DDDetConstr::ConvertMaterial: material=" << material;
00070   G4Material * result = 0;
00071   if (material) {
00072     // only if it's a valid DDD-material
00073     if ((result = mats_[material])) {
00074       LogDebug("SimG4CoreGeometry") << "  is already converted"; 
00075       return result; }
00076   } else {
00077     // only if it's NOT a valid DDD-material
00078     edm::LogError("SimG4CoreGeometry") << "DDG4Builder::  material " << material.toString() << " is not valid (in the DDD sense!)";
00079     throw cms::Exception("SimG4CoreGeometry", " material is not valid from the Detector Description: " + material.toString()); 
00080   }    
00081   int c = 0;
00082   if ((c = material.noOfConstituents())) {
00083     // it's a composite material
00084     LogDebug("SimG4CoreGeometry") << "  creating a G4-composite material. c=" << c
00085                                   << " d=" << material.density()/g*mole ;
00086     result = new G4Material(material.name().name(),material.density(),c);
00087     for (int i=0 ; i<c; ++i) {
00088       // recursive building of constituents
00089       LogDebug("SimG4CoreGeometry") << "  adding the composite=" << material.name()
00090                                     << " fm=" << material.constituent(i).second;
00091       result->AddMaterial
00092         (convertMaterial(material.constituent(i).first),
00093          material.constituent(i).second);// fractionmass
00094     }
00095   } else {
00096     // it's an elementary material
00097     LogDebug("SimG4CoreGeometry") << "  building an elementary material"
00098                                   << " z=" << material.z()
00099                                   << " a=" << material.a()/g*mole
00100                                   << " d=" << material.density()/g*cm3 ;
00101     result = new G4Material
00102       (material.name().name(),material.z(),material.a(),material.density());
00103   }
00104   mats_[material] = result;
00105   return result;
00106 } 
00107 
00108 DDGeometryReturnType DDG4Builder::BuildGeometry() {
00109   G4ReflectionFactory * refFact = G4ReflectionFactory::Instance();
00110   refFact->SetScalePrecision(100.*refFact->GetScalePrecision());
00111 
00112   typedef DDCompactView::graph_type graph_type;
00113   const graph_type & gra = compactView->graph();
00114   typedef graph_type::const_adj_iterator adjl_iterator;
00115   adjl_iterator git = gra.begin();
00116   adjl_iterator gend = gra.end();    
00117 
00118   graph_type::index_type i=0;
00119   for (; git != gend; ++git) {
00120     const DDLogicalPart & ddLP = gra.nodeData(git);
00121     if ( !(ddLP.isDefined().second) ) {
00122       edm::LogError("SimG4CoreGeometry") << "DDG4Builder::BuildGeometry() has encountered an undefined DDLogicalPart named " << ddLP.toString();
00123       throw cms::Exception("SimG4CoreGeometry", " DDG4Builder::BuildGeometry() has encountered an undefined DDLogicalPart named " + ddLP.toString());
00124     }
00125     G4LogicalVolume * g4LV = convertLV(ddLP);
00126     ++i;        
00127     if (git->size()) {
00128       // ask for children of ddLP  
00129       graph_type::edge_list::const_iterator cit  = git->begin();
00130       graph_type::edge_list::const_iterator cend = git->end();
00131       for (; cit != cend; ++cit) {
00132         // fetch specific data
00133         const DDLogicalPart & ddcurLP = gra.nodeData(cit->first);
00134         if ( !ddcurLP.isDefined().second ) {
00135           std::string err = " DDG4Builder::BuildGeometry() in processing \"children\" has ";
00136           err += "encountered an undefined DDLogicalPart named " + ddLP.toString();
00137           edm::LogError("SimG4CoreGeometry") << err;
00138           throw cms::Exception("SimG4CoreGeometry", err) ;
00139         }
00140         int offset = getInt("CopyNoOffset",ddcurLP);
00141         int tag = getInt("CopyNoTag",ddcurLP);                          
00142         DDRotationMatrix rm(gra.edgeData(cit->second)->rot());
00143         DD3Vector x, y, z;
00144         rm.GetComponents(x, y, z);
00145         if ((x.Cross(y)).Dot(z)<0)
00146           LogDebug("SimG4CoreGeometry") << ">>Reflection encountered: " << gra.edgeData(cit->second)->rot_ ;
00147         LogDebug("SimG4CoreGeometry") << ">>Placement d=" << gra.nodeData(cit->first).ddname() 
00148                                       << " m=" << ddLP.ddname() << " cp=" << gra.edgeData(cit->second)->copyno_
00149                                       << " r=" << gra.edgeData(cit->second)->rot_.ddname() ;          
00150         G4ThreeVector tempTran(gra.edgeData(cit->second)->trans_.X(), gra.edgeData(cit->second)->trans_.Y(), gra.edgeData(cit->second)->trans_.Z());
00151         G4Translate3D transl = tempTran;
00152         CLHEP::HepRep3x3 temp( x.X(), x.Y(), x.Z(), y.X(), y.Y(), y.Z(), z.X(), z.Y(), z.Z() ); //matrix representation
00153         CLHEP::HepRotation hr ( temp );
00154             
00155         // G3 convention of defining rot-matrices ...
00156         G4Transform3D trfrm  = transl * G4Rotate3D(hr.inverse());//.inverse();
00157 
00158         refFact->Place(trfrm, // transformation containing a possible reflection
00159                        gra.nodeData(cit->first).name().name(),
00160                        convertLV(gra.nodeData(cit->first)),             // daugther
00161                        g4LV,                                            // mother
00162                        false,                                           // 'ONLY'
00163                        gra.edgeData(cit->second)->copyno_+offset+tag,   // copy number
00164                        check_);
00165       } // iterate over children
00166     } // if (children)
00167   } // iterate over graph nodes  
00168     
00169   // Looking for in the G4ReflectionFactory secretly created reflected G4LogicalVolumes
00170   std::map<DDLogicalPart, G4LogicalVolume*>::const_iterator  ddg4_it = logs_.begin();
00171   for (; ddg4_it != logs_.end(); ++ddg4_it) {
00172     G4LogicalVolume * reflLogicalVolume = refFact->GetReflectedLV(ddg4_it->second);
00173     if (reflLogicalVolume) {
00174       DDLogicalPart ddlv = ddg4_it->first;
00175       map_.insert(reflLogicalVolume,ddlv);
00176       DDG4Dispatchable * disp = new DDG4Dispatchable(&(ddg4_it->first),reflLogicalVolume);
00177       theVectorOfDDG4Dispatchables_->push_back(disp);
00178       LogDebug("SimG4CoreGeometry") << "DDG4Builder: newEvent: dd=" 
00179                                     << ddlv.ddname() << " g4=" 
00180                                     << reflLogicalVolume->GetName();
00181     }  
00182   }
00183       
00184   G4LogicalVolume * world = logs_[compactView->root()];
00185 
00186   //
00187   //  needed for building sensitive detectors
00188   //
00189   DDG4SensitiveConverter conv_;
00190   SensitiveDetectorCatalog catalog = conv_.upDate(*theVectorOfDDG4Dispatchables_);
00191 
00192   return DDGeometryReturnType(world,map_,catalog);    
00193 }
00194 
00195 int DDG4Builder::getInt(const std::string & s, const DDLogicalPart & part)
00196 {
00197   DDValue val(s);
00198   std::vector<const DDsvalues_type *> result = part.specifics();
00199   std::vector<const DDsvalues_type *>::iterator it = result.begin();
00200   bool foundIt = false;
00201   for (; it != result.end(); ++it) {
00202     foundIt = DDfetch(*it,val);
00203     if (foundIt) break;
00204   }    
00205   if (foundIt) { 
00206     std::vector<double> temp = val.doubles();
00207     if (temp.size() != 1) {
00208       edm::LogError("SimG4CoreGeometry") << " DDG4Builder - ERROR: I need only 1 " << s ;
00209       throw SimG4Exception("DDG4Builder: Problem with Region tags - one and only one allowed");
00210     }      
00211     return int(temp[0]);
00212   }
00213   else return 0;
00214 }
00215 
00216 double DDG4Builder::getDouble(const std::string & s, 
00217                               const DDLogicalPart & part) {
00218   DDValue val(s);
00219   std::vector<const DDsvalues_type *> result = part.specifics();
00220   std::vector<const DDsvalues_type *>::iterator it = result.begin();
00221   bool foundIt = false;
00222   for (; it != result.end(); ++it) {
00223     foundIt = DDfetch(*it,val);
00224     if (foundIt) break;
00225   }    
00226   if (foundIt) { 
00227     std::vector<std::string> temp = val.strings();
00228     if (temp.size() != 1) {
00229       edm::LogError("SimG4CoreGeometry") << " DDG4Builder - ERROR: I need only 1 " << s ;
00230       throw SimG4Exception("DDG4Builder: Problem with Region tags - one and only one allowed");
00231     }
00232     double v;
00233     std::string unit;
00234     std::istringstream is(temp[0].c_str());
00235     is >> v >> unit;
00236     v  = v*G4UnitDefinition::GetValueOf(unit.substr(1,unit.size()));
00237     return v;
00238   }
00239   else return 0;
00240 }