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;
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
00073 if ((result = mats_[material])) {
00074 LogDebug("SimG4CoreGeometry") << " is already converted";
00075 return result; }
00076 } else {
00077
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
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
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);
00094 }
00095 } else {
00096
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
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
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() );
00153 CLHEP::HepRotation hr ( temp );
00154
00155
00156 G4Transform3D trfrm = transl * G4Rotate3D(hr.inverse());
00157
00158 refFact->Place(trfrm,
00159 gra.nodeData(cit->first).name().name(),
00160 convertLV(gra.nodeData(cit->first)),
00161 g4LV,
00162 false,
00163 gra.edgeData(cit->second)->copyno_+offset+tag,
00164 check_);
00165 }
00166 }
00167 }
00168
00169
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
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 }