G4STRead.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // $Id: G4STRead.cc 69813 2013-05-15 15:44:33Z gcosmo $
00027 //
00028 // class G4STRead Implementation
00029 //
00030 // History:
00031 // - Created.                                  Zoltan Torzsok, November 2007
00032 // -------------------------------------------------------------------------
00033 
00034 #include <fstream>
00035 
00036 #include "G4STRead.hh"
00037 
00038 #include "G4Material.hh"
00039 #include "G4Box.hh"
00040 #include "G4QuadrangularFacet.hh"
00041 #include "G4TriangularFacet.hh"
00042 #include "G4TessellatedSolid.hh"
00043 #include "G4LogicalVolume.hh"
00044 #include "G4PVPlacement.hh"
00045 #include "G4AffineTransform.hh"
00046 #include "G4VoxelLimits.hh"
00047 
00048 void G4STRead::TessellatedRead(const std::string& line)
00049 {
00050    if (tessellatedList.size()>0)
00051    {
00052      tessellatedList.back()->SetSolidClosed(true);
00053        // Finish the previous solid at first!
00054    }
00055 
00056    std::istringstream stream(line.substr(2));
00057    
00058    G4String name;
00059    stream >> name;
00060    
00061    G4TessellatedSolid* tessellated = new G4TessellatedSolid(name);
00062    volumeMap[tessellated] =
00063      new G4LogicalVolume(tessellated, solid_material, name+"_LV" , 0, 0, 0);
00064    tessellatedList.push_back(tessellated);
00065 
00066    G4cout << "G4STRead: Reading solid: " << name << G4endl;
00067 }
00068 
00069 void G4STRead::FacetRead(const std::string& line)
00070 {
00071    if (tessellatedList.size()==0)
00072    {
00073      G4Exception("G4STRead::FacetRead()", "ReadError", FatalException,
00074                  "A solid must be defined before defining a facet!");
00075    }
00076 
00077    if (line[2]=='3')  // Triangular facet
00078    {
00079       G4double x1,y1,z1;
00080       G4double x2,y2,z2;
00081       G4double x3,y3,z3;
00082       
00083       std::istringstream stream(line.substr(4));
00084       stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> x3 >> y3 >> z3;
00085       tessellatedList.back()->
00086         AddFacet(new G4TriangularFacet(G4ThreeVector(x1,y1,z1),
00087                                        G4ThreeVector(x2,y2,z2),
00088                                        G4ThreeVector(x3,y3,z3), ABSOLUTE));
00089    }
00090    else if (line[2]=='4')  // Quadrangular facet
00091    {
00092       G4double x1,y1,z1;
00093       G4double x2,y2,z2;
00094       G4double x3,y3,z3;
00095       G4double x4,y4,z4;
00096 
00097       std::istringstream stream(line.substr(4));
00098       stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2
00099              >> x3 >> y3 >> z3 >> x4 >> y4 >> z4;
00100       tessellatedList.back()->
00101         AddFacet(new G4QuadrangularFacet(G4ThreeVector(x1,y1,z1),
00102                                          G4ThreeVector(x2,y2,z2),
00103                                          G4ThreeVector(x3,y3,z3),
00104                                          G4ThreeVector(x4,y4,z4), ABSOLUTE));
00105    }
00106    else
00107    {
00108      G4Exception("G4STRead::FacetRead()", "ReadError", FatalException,
00109                  "Number of vertices per facet should be either 3 or 4!");
00110    }
00111 }
00112 
00113 void G4STRead::PhysvolRead(const std::string& line)
00114 {
00115    G4int level;
00116    G4String name;
00117    G4double r1,r2,r3;
00118    G4double r4,r5,r6;
00119    G4double r7,r8,r9;
00120    G4double pX,pY,pZ;
00121    G4double n1,n2,n3,n4,n5;
00122 
00123    std::istringstream stream(line.substr(2));
00124    stream >> level >> name >> r1 >> r2 >> r3 >> n1 >> r4 >> r5 >> r6
00125           >> n2 >> r7 >> r8 >> r9 >> n3 >> pX >> pY >> pZ >> n4 >> n5;
00126    std::string::size_type idx = name.rfind("_");
00127    if (idx!=std::string::npos)
00128    {
00129      name.resize(idx);
00130    }
00131    else
00132    {
00133      G4Exception("G4STRead::PhysvolRead()", "ReadError",
00134                  FatalException, "Invalid input stream!");
00135      return;
00136    }
00137 
00138    G4cout << "G4STRead: Placing tessellated solid: " << name << G4endl;
00139 
00140    G4TessellatedSolid* tessellated = 0;
00141 
00142    for (size_t i=0; i<tessellatedList.size(); i++)
00143    {                                    // Find the volume for this physvol!
00144       if (tessellatedList[i]->GetName() == G4String(name))
00145       {
00146          tessellated = tessellatedList[i];
00147          break;
00148       }
00149    }
00150 
00151    if (tessellated == 0)
00152    {
00153      G4String error_msg = "Referenced solid '" + name + "' not found!";
00154      G4Exception("G4STRead::PhysvolRead()", "ReadError",
00155                  FatalException, error_msg);
00156    }
00157    if (volumeMap.find(tessellated) == volumeMap.end())
00158    {
00159      G4String error_msg = "Referenced solid '" + name
00160                         + "' is not associated with a logical volume!";
00161      G4Exception("G4STRead::PhysvolRead()", "InvalidSetup",
00162                  FatalException, error_msg);
00163    }
00164    const G4RotationMatrix rot(G4ThreeVector(r1,r2,r3),
00165                               G4ThreeVector(r4,r5,r6),
00166                               G4ThreeVector(r7,r8,r9));
00167    const G4ThreeVector pos(pX,pY,pZ);
00168 
00169    new G4PVPlacement(G4Transform3D(rot.inverse(),pos),
00170                      volumeMap[tessellated], name+"_PV", world_volume, 0, 0);
00171      // Note: INVERSE of rotation is needed!!!
00172 
00173    G4double minx,miny,minz;
00174    G4double maxx,maxy,maxz;
00175    const G4VoxelLimits limits;
00176 
00177    tessellated->CalculateExtent(kXAxis,limits,
00178                 G4AffineTransform(rot,pos),minx,maxx);
00179    tessellated->CalculateExtent(kYAxis,limits,
00180                 G4AffineTransform(rot,pos),miny,maxy);
00181    tessellated->CalculateExtent(kZAxis,limits,
00182                 G4AffineTransform(rot,pos),minz,maxz);
00183 
00184    if (world_extent.x() < std::fabs(minx))
00185      { world_extent.setX(std::fabs(minx)); }
00186    if (world_extent.y() < std::fabs(miny))
00187      { world_extent.setY(std::fabs(miny)); }
00188    if (world_extent.z() < std::fabs(minz))
00189      { world_extent.setZ(std::fabs(minz)); }
00190    if (world_extent.x() < std::fabs(maxx))
00191      { world_extent.setX(std::fabs(maxx)); }
00192    if (world_extent.y() < std::fabs(maxy))
00193      { world_extent.setY(std::fabs(maxy)); }
00194    if (world_extent.z() < std::fabs(maxz))
00195      { world_extent.setZ(std::fabs(maxz)); }
00196 }
00197 
00198 void G4STRead::ReadGeom(const G4String& name)
00199 {
00200    G4cout << "G4STRead: Reading '" << name << "'..." << G4endl;
00201 
00202    std::ifstream GeomFile(name);
00203    
00204    if (!GeomFile)
00205    {
00206       G4String error_msg = "Cannot open file: " + name;
00207       G4Exception("G4STRead::ReadGeom()", "ReadError",
00208                   FatalException, error_msg);
00209    }
00210 
00211    tessellatedList.clear();
00212    volumeMap.clear();
00213    std::string line;
00214    
00215    while (getline(GeomFile,line))
00216    {
00217       if (line[0] == 'f') { TessellatedRead(line); } else
00218       if (line[0] == 'p') { FacetRead(line); }
00219    }
00220 
00221    if (tessellatedList.size()>0)   // Finish the last solid!
00222    {
00223       tessellatedList.back()->SetSolidClosed(true);
00224    }
00225 
00226    G4cout << "G4STRead: Reading '" << name << "' done." << G4endl;
00227 }
00228 
00229 void G4STRead::ReadTree(const G4String& name)
00230 {
00231    G4cout << "G4STRead: Reading '" << name << "'..." << G4endl;
00232 
00233    std::ifstream TreeFile(name);
00234 
00235    if (!TreeFile)
00236    {
00237       G4String error_msg = "Cannot open file: " + name;
00238       G4Exception("G4STRead::ReadTree()", "ReadError",
00239                   FatalException, error_msg);
00240    }
00241 
00242    std::string line;
00243    
00244    while (getline(TreeFile,line))
00245    {
00246       if (line[0] == 'g')  { PhysvolRead(line); }
00247    }
00248 
00249    G4cout << "G4STRead: Reading '" << name << "' done." << G4endl;
00250 }
00251 
00252 G4LogicalVolume*
00253 G4STRead::Read(const G4String& name, G4Material* mediumMaterial,
00254                                      G4Material* solidMaterial)
00255 {
00256    if (mediumMaterial == 0)
00257    {
00258      G4Exception("G4STRead::Read()", "InvalidSetup", FatalException,
00259                  "Pointer to medium material is not valid!");
00260    }
00261    if (solidMaterial == 0)
00262    {
00263      G4Exception("G4STRead::Read()", "InvalidSetup", FatalException,
00264                  "Pointer to solid material is not valid!");
00265    }
00266 
00267    solid_material = solidMaterial;
00268 
00269    world_box = new G4Box("TessellatedWorldBox",kInfinity,kInfinity,kInfinity);
00270      // We don't know the extent of the world yet!
00271    world_volume = new G4LogicalVolume(world_box, mediumMaterial,
00272                                       "TessellatedWorldLV", 0, 0, 0);
00273    world_extent = G4ThreeVector(0,0,0);
00274 
00275    ReadGeom(name+".geom");
00276    ReadTree(name+".tree");
00277 
00278    // Now setting the world extent ...
00279    //
00280    if (world_box->GetXHalfLength() > world_extent.x())
00281      { world_box->SetXHalfLength(world_extent.x()); }
00282    if (world_box->GetYHalfLength() > world_extent.y())
00283      { world_box->SetYHalfLength(world_extent.y()); }
00284    if (world_box->GetZHalfLength() > world_extent.z())
00285      { world_box->SetZHalfLength(world_extent.z()); }
00286 
00287    return world_volume;
00288 }

Generated on Mon May 27 17:49:55 2013 for Geant4 by  doxygen 1.4.7