// $Id$
// Category: geometry
-// by I. Hrivnacova, 27.07.2000
//
+// Author: I. Hrivnacova, 27.07.2000
+//
+// Class TG4XMLGeometryGenerator
+// -----------------------------
// See the class description in the header file.
#include "TG4XMLGeometryGenerator.h"
#include <G4LogicalVolume.hh>
#include <G4VPhysicalVolume.hh>
#include <G4PVPlacement.hh>
+#include <G4PVReplica.hh>
#include <G4ThreeVector.hh>
#include <G4RotationMatrix.hh>
TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
-TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
+//_____________________________________________________________________________
+TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
+ : TG4Verbose("geometryGenerator")
{
//
if (fgInstance) {
fConvertor = new TG4XMLConvertor(fOutFile);
}
-TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(const TG4XMLGeometryGenerator& right)
+//_____________________________________________________________________________
+TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(
+ const TG4XMLGeometryGenerator& right)
+ : TG4Verbose("geometryGenerator")
{
//
TG4Globals::Exception(
"TG4XMLGeometryGenerator: attempt to copy singleton.");
}
-
+//_____________________________________________________________________________
TG4XMLGeometryGenerator::~TG4XMLGeometryGenerator() {
//
}
// operators
+//_____________________________________________________________________________
TG4XMLGeometryGenerator&
TG4XMLGeometryGenerator::operator=(const TG4XMLGeometryGenerator& right)
{
// private methods
+//_____________________________________________________________________________
+void TG4XMLGeometryGenerator::CutName(G4String& name) const
+{
+// Removes spaces after the name if present.
+// ---
+
+ G4int i = name.length();
+ while (name(--i) == ' ') name = name(0,i);
+}
+
+//_____________________________________________________________________________
void TG4XMLGeometryGenerator::ProcessSolids(G4LogicalVolume* lv)
{
// Writes all solids of given logical volume.
// ---
G4VSolid* solid = lv->GetSolid();
+ G4String lvName = lv->GetName();
G4String material = lv->GetMaterial()->GetName();
- fConvertor->WriteSolid(solid, material);
+ fConvertor->WriteSolid(lvName, solid, material);
+ // store the name of logical volume in the set
+ fVolumeNames.insert(fVolumeNames.begin(), lvName);
+
+ // process daughters
G4int nofDaughters = lv->GetNoDaughters();
if (nofDaughters>0)
for (G4int i=0; i<nofDaughters; i++) {
+
+ if (VerboseLevel() > 1) {
+ G4cout << "processing " << i << "th daughter of "
+ << lv->GetName() << G4endl;
+ }
+
G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
- ProcessSolids(lvd);
+ G4String lvdName = lvd->GetName();
+
+ if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
+ // process lvd only if it was not yet processed
+ ProcessSolids(lvd);
+ }
}
}
+//_____________________________________________________________________________
void TG4XMLGeometryGenerator::ProcessMaterials(G4LogicalVolume* lv)
{
// Writes all materials of given logical volume.
// ---
G4Material* material = lv->GetMaterial();
- fConvertor->WriteMaterial(material);
+ // check if this material was already written
+ G4bool written = false;
+ G4String name = material->GetName();
+ CutName(name);
+ if (fMaterialNames.find(name) != fMaterialNames.end()) written = true;
+
+ if (!written) {
+ fConvertor->WriteMaterial(material);
+ fMaterialNames.insert(fMaterialNames.begin(), name);
+ }
+
+ // store the name of logical volume in the set
+ G4String lvName = lv->GetName();
+ fVolumeNames.insert(fVolumeNames.begin(), lvName);
+
G4int nofDaughters = lv->GetNoDaughters();
if (nofDaughters>0)
for (G4int i=0; i<nofDaughters; i++) {
G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
- ProcessMaterials(lvd);
+ G4String lvdName = lvd->GetName();
+
+ if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
+ // process lvd only if it was not yet processed
+ ProcessMaterials(lvd);
+ }
}
}
+//_____________________________________________________________________________
void TG4XMLGeometryGenerator::ProcessRotations(G4LogicalVolume* lv)
{
// Writes all rotation matrices of given logical volume.
// ---
+ G4String lvName = lv->GetName();
+
+ // store the name of logical volume in the set
+ fVolumeNames.insert(fVolumeNames.begin(), lvName);
+
G4int nofDaughters = lv->GetNoDaughters();
- if (nofDaughters>0)
- for (G4int i=0; i<nofDaughters; i++) {
+
+ if (nofDaughters>0) {
+ G4int i;
+ for (i=0; i<nofDaughters; i++) {
+
G4VPhysicalVolume* pvd = lv->GetDaughter(i);
const G4RotationMatrix* kRotation = pvd->GetRotation();
- if (kRotation) fConvertor->WriteRotation(kRotation);
+ if (kRotation)
+ fConvertor->WriteRotation(kRotation);
+
G4LogicalVolume* lvd = pvd->GetLogicalVolume();
- ProcessRotations(lvd);
+ G4String lvdName = lvd->GetName();
+
+ if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
+ // process lvd only if it was not yet processed
+ ProcessRotations(lvd);
+ }
}
+ }
}
+//_____________________________________________________________________________
void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv)
{
// Writes logical volume tree.
if (nofDaughters == 0) return;
// open composition
- G4String name = lv->GetName();
+ G4String lvName = lv->GetName();
+ G4String name = lvName;
name.append("_comp");
fConvertor->OpenComposition(name);
-
+
// write positions
- for (G4int i=0; i<nofDaughters; i++) {
+ G4int i;
+ for (i=0; i<nofDaughters; i++) {
+
+ if (VerboseLevel() > 1) {
+ G4cout << "processing " << i << "th daughter of "
+ << lv->GetName() << G4endl;
+ }
+
G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
G4LogicalVolume* lvd = vpvd->GetLogicalVolume();
- // only placements are processed
+ // get parameters
+ G4String lvName = lvd->GetName();
+ G4String compName = lvd->GetName();
+ compName.append("_comp");
+ G4int nd = lvd->GetNoDaughters();
+
G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
if (pvd) {
- G4String solidName = lvd->GetSolid()->GetName();
- G4String compName = lvd->GetName();
- compName.append("_comp");
- G4int nd = lvd->GetNoDaughters();
- G4ThreeVector position = vpvd->GetFrameTranslation();
- const G4RotationMatrix* kMatrix = vpvd->GetFrameRotation();
-
- if (!kMatrix) {
- fConvertor->WritePosition(solidName, position);
+ // placement
+ G4ThreeVector position = vpvd->GetTranslation();
+
+ if (!vpvd->GetRotation()) {
+ fConvertor->WritePosition(lvName, position);
// if volume is not leaf node place its logical volume
if (nd>0)
fConvertor->WritePosition(compName, position);
}
else {
- fConvertor->WritePositionWithRotation(solidName, position, kMatrix);
+ const G4RotationMatrix* kMatrix = vpvd->GetObjectRotation();
+ fConvertor->WritePositionWithRotation(lvName, position, kMatrix);
if (nd>0)
fConvertor->WritePositionWithRotation(compName, position, kMatrix);
- }
-
+ }
}
else {
- G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
- text = text + " Limitation: \n";
- text = text + " Other physical volumes than PVPlacement";
- text = text + " are not implemented.";
- TG4Globals::Warning(text);
- }
+ G4PVReplica* pvr = dynamic_cast<G4PVReplica*>(vpvd);
+ if (pvr) {
+ // replica
+ fConvertor->WriteReplica(lvName, pvr);
+ // if volume is not leaf node place its logical volume
+ if (nd>0)
+ fConvertor->WriteReplica(compName, pvr);
+ }
+ else {
+ G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
+ text = text + " Limitation: \n";
+ text = text + " Other physical volumes than PVPlacement and PVReplica";
+ text = text + " are not implemented.";
+ TG4Globals::Exception(text);
+ }
+ }
}
// close composition
fConvertor->CloseComposition();
fConvertor->WriteEmptyLine();
- // make a vector of contained logical volumes
- // with daughters
- // -> change to a global map of names of written compositions
- // and test against this map
- G4std::vector<G4LogicalVolume*> vect;
- for (G4int i=0; i<nofDaughters; i++) {
+ // store the name of logical volume in the set
+ fVolumeNames.insert(fVolumeNames.begin(), lvName);
+
+ // process daughters
+ for (i=0; i<nofDaughters; i++) {
G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
- G4bool store = true;
- for (G4int j=0; j<vect.size(); j++)
- if (vect[j] == lvd || lvd->GetNoDaughters()==0) store = false;
- if (store) vect.push_back(lvd);
- }
-
- // process contained logical volumes with daughters
- fConvertor->IncreaseIndention();
- for (G4int j=0; j<vect.size(); j++)
- ProcessLogicalVolume(vect[j]);
- fConvertor->DecreaseIndention();
+ G4String lvdName = lvd->GetName();
+
+ if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
+ // process lvd only if it was not yet processed
+ ProcessLogicalVolume(lvd);
+ }
+ }
}
-/*
-void TG4XMLGeometryGenerator::ProcessLogicalVolumeOld(G4LogicalVolume* lv)
+//_____________________________________________________________________________
+void TG4XMLGeometryGenerator::ClearMaterialNames()
{
-// Writes logical volume tree.
+// Clears the set of material names.
// ---
-
- G4int nofDaughters = lv->GetNoDaughters();
- if (nofDaughters == 0) return;
-
- // make a vector of contained logical volumes
- G4std::vector<G4LogicalVolume*> vect;
- for (G4int i=0; i<nofDaughters; i++) {
- G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
- G4bool store = true;
- for (G4int j=0; j<vect.size(); j++)
- if (vect[j] == lvd) store = false;
- if (store) vect.push_back(lvd);
- }
-
- // loop over contained logical volumes
- for (G4int j=0; j<vect.size(); j++) {
- G4LogicalVolume* lvd = vect[j];
-
- // open composition
- if(lvd->GetNoDaughters()>0) {
- G4String name = lvd->GetName();
- name.append("_lv");
- fConvertor->OpenComposition(name);
- }
-
- // write positions
- for (G4int i=0; i<nofDaughters; i++) {
- G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
- G4LogicalVolume* lvdi = vpvd->GetLogicalVolume();
-
- if (lvdi == lvd) {
- // only placements are processed
- G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
- if (pvd) {
- G4String solidName = lvd->GetSolid()->GetName();
- G4ThreeVector position = vpvd->GetFrameTranslation();
- const G4RotationMatrix* kMatrix = vpvd->GetFrameRotation();
- if (!kMatrix)
- fConvertor->WritePosition(solidName, position);
- else
- fConvertor->WritePositionWithRotation(solidName, position, kMatrix);
- }
- else {
- G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
- text = text + " Limitation: \n";
- text = text + " Other physical volumes than PVPlacement";
- text = text + " are not implemented.";
- TG4Globals::Warning(text);
- }
- }
- }
- if(lvd->GetNoDaughters()>0) {
- // process daughters recursively
- ProcessLogicalVolume(lvd);
- fConvertor->CloseComposition();
- fConvertor->WriteEmptyLine();
- }
- }
+ fMaterialNames.erase(fMaterialNames.begin(), fMaterialNames.end());
+}
+
+//_____________________________________________________________________________
+void TG4XMLGeometryGenerator::ClearVolumeNames()
+{
+// Clears the set of volume names.
+// ---
+
+ fVolumeNames.erase(fVolumeNames.begin(), fVolumeNames.end());
}
-*/
// public methods
+//_____________________________________________________________________________
void TG4XMLGeometryGenerator::GenerateMaterials(
const G4String& version, const G4String& date,
const G4String& author, const G4String dtdVersion,
// process materials
ProcessMaterials(lv);
fConvertor->WriteEmptyLine();
+ ClearMaterialNames();
+ ClearVolumeNames();
// close section
fConvertor->CloseMaterials();
fConvertor->WriteEmptyLine();
}
+//_____________________________________________________________________________
void TG4XMLGeometryGenerator::GenerateSection(const G4String& name,
const G4String& version, const G4String& date,
const G4String& author, const G4String& topVolume,
fConvertor->WriteEmptyLine();
// process rotations
- ProcessRotations(lv);
- fConvertor->WriteEmptyLine();
+ //ProcessRotations(lv);
+ //fConvertor->WriteEmptyLine();
+ //ClearRotations();
+ //ClearVolumeNames();
// process solids
ProcessSolids(lv);
fConvertor->WriteEmptyLine();
+ ClearVolumeNames();
// process geometry tree
ProcessLogicalVolume(lv);
fConvertor->WriteEmptyLine();
+ ClearVolumeNames();
// close section
fConvertor->CloseSection();
}
+//_____________________________________________________________________________
void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
{
// Opens output file.
// ---
- G4cout << "TG4XMLGeometryGenerator::OpenFile: " << filePath << G4endl;
-
fOutFile.open(filePath, G4std::ios::out);
if (!fOutFile) {
}
+//_____________________________________________________________________________
void TG4XMLGeometryGenerator::CloseFile()
{
// Closes output file.