]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TGeant4/TG4XMLGeometryGenerator.cxx
Changes by Massimo Masera to allow Recpoints and Clusters to be written
[u/mrichter/AliRoot.git] / TGeant4 / TG4XMLGeometryGenerator.cxx
index e7f68cbfb41f7e7b48093302a7f0ef091d95ae1d..7b322852c96df429c199d1d7a39d320da677504f 100644 (file)
@@ -1,7 +1,10 @@
 // $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"
@@ -13,6 +16,7 @@
 #include <G4LogicalVolume.hh>
 #include <G4VPhysicalVolume.hh>
 #include <G4PVPlacement.hh>
+#include <G4PVReplica.hh>
 #include <G4ThreeVector.hh>
 #include <G4RotationMatrix.hh>
 
@@ -21,7 +25,9 @@
 
 TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
 
-TG4XMLGeometryGenerator::TG4XMLGeometryGenerator() 
+//_____________________________________________________________________________
+TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
+  : TG4Verbose("geometryGenerator") 
 {
 //
   if (fgInstance) {
@@ -32,20 +38,24 @@ TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
   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)
 {
@@ -61,55 +71,120 @@ 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.
@@ -119,140 +194,106 @@ void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv)
   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,
@@ -269,12 +310,15 @@ void TG4XMLGeometryGenerator::GenerateMaterials(
   // 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,
@@ -290,28 +334,31 @@ void TG4XMLGeometryGenerator::GenerateSection(const G4String& name,
   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) {
@@ -325,6 +372,7 @@ void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
 }
 
 
+//_____________________________________________________________________________
 void TG4XMLGeometryGenerator::CloseFile()
 { 
 // Closes output file.