Import Geant4 4.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-08 16:18:25 +02:00
parent 36c080dca6
commit 921d3b1cda
3990 changed files with 185376 additions and 82884 deletions
@@ -0,0 +1,163 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4GeomTestErrorList.cc,v 1.1 2001/10/17 12:59:57 gcosmo Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// --------------------------------------------------------------------
// GEANT 4 class source file
//
// G4GeomTestErrorList
//
// Author: D.C.Williams, UCSC (davidw@scipp.ucsc.edu)
#include "G4GeomTestErrorList.hh"
#include "G4VPhysicalVolume.hh"
//
// Constructor
//
G4GeomTestErrorList::G4GeomTestErrorList( const G4VPhysicalVolume *theMother )
: mother(theMother)
{
FindGlobalCoordinateSystem();
}
//
// Destructor
//
G4GeomTestErrorList::~G4GeomTestErrorList() {;}
//
// AddError
//
// Add a new Error point to our list, where the point
// is given in the coordinate system of the mother
//
void G4GeomTestErrorList::AddError( const G4ThreeVector &s1,
const G4ThreeVector &s2 )
{
segments.push_back( Segment(s1,s2) );
}
//
// Accessors
//
const G4VPhysicalVolume *G4GeomTestErrorList::GetMother() const
{
return mother;
}
//
// Return number of segments
//
G4int G4GeomTestErrorList::NumError() const
{
return segments.size();
}
//
// GetMotherPoints
//
// Return start and end points in the coordinate system
// of the mother
//
void G4GeomTestErrorList::GetMotherPoints( G4int i,
G4ThreeVector &s1,
G4ThreeVector &s2 ) const
{
s1 = segments[i].GetS1();
s2 = segments[i].GetS2();
}
//
// GetGlobalPoints
//
// Return start and end points in the global coordinate system
//
void G4GeomTestErrorList::GetGlobalPoints( G4int i,
G4ThreeVector &s1,
G4ThreeVector &s2 ) const
{
s1 = globalTranslation + globalRotation*segments[i].GetS1();
s2 = globalTranslation + globalRotation*segments[i].GetS2();
}
//
// GetOneDaughtPoints
//
// Return start and end points in the coordinate system of
// a daughter
//
void G4GeomTestErrorList::GetOneDaughtPoints( const G4VPhysicalVolume *daught,
G4int i,
G4ThreeVector &s1,
G4ThreeVector &s2 ) const
{
const G4RotationMatrix *rotation = daught->GetFrameRotation();
const G4ThreeVector &translation = daught->GetFrameTranslation();
if (rotation) {
s1 = (*rotation)*(translation + segments[i].GetS1());
s2 = (*rotation)*(translation + segments[i].GetS2());
}
else {
s1 = translation + segments[i].GetS1();
s2 = translation + segments[i].GetS2();
}
}
//
// FindGlobalCoordinateSystem
//
// Calculate translation to global coordinates
//
void G4GeomTestErrorList::FindGlobalCoordinateSystem()
{
globalTranslation = G4ThreeVector(0,0,0);
globalRotation = G4RotationMatrix();
const G4VPhysicalVolume *vol = mother;
for(;;) {
const G4VPhysicalVolume *parent = vol->GetMother();
if (parent == 0) break;
const G4RotationMatrix &rotation = vol->GetObjectRotationValue();
const G4ThreeVector &translation = vol->GetObjectTranslation();
globalTranslation = translation + rotation*globalTranslation;
globalRotation = rotation*globalRotation;
vol = parent;
}
}
@@ -0,0 +1,137 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4GeomTestOverlapList.cc,v 1.1 2001/10/17 12:59:58 gcosmo Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// --------------------------------------------------------------------
// GEANT 4 class source file
//
// G4GeomTestOverlapList
//
// Author: D.C.Williams, UCSC (davidw@scipp.ucsc.edu)
#include "G4GeomTestOverlapList.hh"
#include "G4VPhysicalVolume.hh"
#include "G4LogicalVolume.hh"
//
// Constructor
//
G4GeomTestOverlapList::G4GeomTestOverlapList(
const G4VPhysicalVolume *theMother,
G4int theDaughter1,
G4int theDaughter2 )
: G4GeomTestErrorList(theMother),
daughter1(theDaughter1),
daughter2(theDaughter2)
{;}
//
// Default constructor
//
G4GeomTestOverlapList::G4GeomTestOverlapList()
: G4GeomTestErrorList(0),
daughter1(0),
daughter2(0)
{;}
//
// Destructor
//
G4GeomTestOverlapList::~G4GeomTestOverlapList() {;}
//
// Comparison operators
//
G4bool
G4GeomTestOverlapList::operator==( const G4GeomTestOverlapList &other ) const
{
return daughter1==other.daughter1 && daughter2==other.daughter2;
}
G4bool
G4GeomTestOverlapList::operator< ( const G4GeomTestOverlapList &other ) const
{
if (daughter1 > other.daughter1) return false;
if (daughter1 < other.daughter1) return true;
return (daughter2 < other.daughter2);
}
//
// Accessors
//
const G4VPhysicalVolume *G4GeomTestOverlapList::GetDaughter1() const
{
return GetMother()->GetLogicalVolume()->GetDaughter(daughter1);
}
const G4VPhysicalVolume *G4GeomTestOverlapList::GetDaughter2() const
{
return GetMother()->GetLogicalVolume()->GetDaughter(daughter2);
}
G4int G4GeomTestOverlapList::GetDaughter1Index() const
{
return daughter1;
}
G4int G4GeomTestOverlapList::GetDaughter2Index() const
{
return daughter2;
}
//
// GetDaught1Points
//
// Return start and end points in the coordinate system of
// the first daughter
//
void G4GeomTestOverlapList::GetDaught1Points( G4int i,
G4ThreeVector &s1,
G4ThreeVector &s2 ) const
{
GetOneDaughtPoints( GetDaughter1(), i, s1, s2 );
}
//
// GetDaught2Points
//
// Return start and end points in the coordinate system of
// the second daughter
//
void G4GeomTestOverlapList::GetDaught2Points( G4int i,
G4ThreeVector &s1,
G4ThreeVector &s2 ) const
{
GetOneDaughtPoints( GetDaughter2(), i, s1, s2 );
}
@@ -0,0 +1,107 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4GeomTestOvershootList.cc,v 1.1 2001/10/17 12:59:58 gcosmo Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// --------------------------------------------------------------------
// GEANT 4 class source file
//
// G4GeomTestOvershootList
//
// Author: D.C.Williams, UCSC (davidw@scipp.ucsc.edu)
#include "G4GeomTestOvershootList.hh"
#include "G4VPhysicalVolume.hh"
#include "G4LogicalVolume.hh"
//
// Constructor
//
G4GeomTestOvershootList::G4GeomTestOvershootList(
const G4VPhysicalVolume *theMother,
G4int theDaughterIndex )
: G4GeomTestErrorList(theMother),
daughter(theDaughterIndex)
{;}
//
// Default constructor
//
G4GeomTestOvershootList::G4GeomTestOvershootList()
: G4GeomTestErrorList(0),
daughter(0)
{;}
//
// Destructor
//
G4GeomTestOvershootList::~G4GeomTestOvershootList() {;}
//
// Comparison operators
//
G4bool
G4GeomTestOvershootList::operator==( const G4GeomTestOvershootList &other ) const
{
return daughter==other.daughter;
}
G4bool
G4GeomTestOvershootList::operator< ( const G4GeomTestOvershootList &other ) const
{
return (daughter < other.daughter);
}
//
// Accessors
//
const G4VPhysicalVolume *G4GeomTestOvershootList::GetDaughter() const
{
return GetMother()->GetLogicalVolume()->GetDaughter(daughter);
}
G4int G4GeomTestOvershootList::GetDaughterIndex() const
{
return daughter;
}
//
// GetDaughtPoints
//
// Return start and end points in the coordinate system of
// the daughter
//
void G4GeomTestOvershootList::GetDaughtPoints( G4int i,
G4ThreeVector &s1,
G4ThreeVector &s2 ) const
{
GetOneDaughtPoints( GetDaughter(), i, s1, s2 );
}
@@ -0,0 +1,123 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4GeomTestPoint.cc,v 1.1 2001/10/17 12:59:58 gcosmo Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// --------------------------------------------------------------------
// GEANT 4 class source file
//
// G4GeomTestPoint
//
// Author: D.C.Williams, UCSC (davidw@scipp.ucsc.edu)
#include "G4GeomTestPoint.hh"
//
// Default constructor
//
G4GeomTestPoint::G4GeomTestPoint()
: p(0),
s(0),
entering(false)
{;}
//
// Specific constructor
//
G4GeomTestPoint::G4GeomTestPoint( const G4ThreeVector &thePoint,
G4double theS,
G4bool isEntering )
: p(thePoint),
s(theS),
entering(isEntering)
{;}
//
// Copy constructor
//
G4GeomTestPoint::G4GeomTestPoint( const G4GeomTestPoint &other )
: p(other.p),
s(other.s),
entering(other.entering)
{;}
//
// Destructor
//
G4GeomTestPoint::~G4GeomTestPoint() {;}
//
// Equivalence operator
//
G4bool G4GeomTestPoint::operator==( const G4GeomTestPoint &other ) const
{
return s == other.s;
}
//
// Order operators
//
G4bool G4GeomTestPoint::operator<( const G4GeomTestPoint &other ) const
{
return s < other.s;
}
G4bool G4GeomTestPoint::operator<=( const G4GeomTestPoint &other ) const
{
return s <= other.s;
}
//
// Return position
//
const G4ThreeVector &G4GeomTestPoint::GetPosition() const
{
return p;
}
//
// Return distance
//
G4double G4GeomTestPoint::GetDistance() const
{
return s;
}
//
// Return true if point was entering
//
G4bool G4GeomTestPoint::Entering() const
{
return entering;
}
@@ -0,0 +1,371 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4GeomTestSegment.cc,v 1.1 2001/10/17 12:59:59 gcosmo Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// --------------------------------------------------------------------
// GEANT 4 class source file
//
// G4GeomTestSegment
//
// Author: D.C.Williams, UCSC (davidw@scipp.ucsc.edu)
#include "G4GeomTestSegment.hh"
#include "G4VSolid.hh"
#include "G4GeomTestLogger.hh"
//
// Constructor
//
G4GeomTestSegment::G4GeomTestSegment( const G4VSolid *theSolid,
const G4ThreeVector &theP,
const G4ThreeVector &theV,
G4GeomTestLogger *logger )
: solid(theSolid),
p0(theP),
v(theV)
{
FindPoints(logger);
}
//
// Simple accessors
//
const G4VSolid * G4GeomTestSegment::GetSolid() const { return solid; }
const G4ThreeVector &G4GeomTestSegment::GetP() const { return p0; }
const G4ThreeVector &G4GeomTestSegment::GetV() const { return v; }
//
// Return number points
//
G4int G4GeomTestSegment::GetNumberPoints() const
{
return points.size();
}
//
// Return ith point
//
const G4GeomTestPoint &G4GeomTestSegment::GetPoint( G4int i ) const
{
return points[i];
}
//
// FindPoints
//
// Do the dirty work
//
void G4GeomTestSegment::FindPoints( G4GeomTestLogger *logger )
{
FindSomePoints( logger, true );
FindSomePoints( logger, false );
PatchInconsistencies( logger );
}
//
// PatchInconsistencies
//
// Search for inconsistancies in the hit list and patch
// them up, if possible
//
void G4GeomTestSegment::PatchInconsistencies( G4GeomTestLogger *logger )
{
if (points.size() == 0) return;
//
// Sort
//
G4std::sort( points.begin(), points.end() );
//
// Loop over entering/leaving pairs
//
G4std::vector<G4GeomTestPoint>::iterator curr = points.begin();
do {
G4std::vector<G4GeomTestPoint>::iterator next = curr + 1;
//
// Is the next point close by?
//
while (next != points.end() &&
next->GetDistance()-curr->GetDistance() < kCarTolerance) {
//
// Yup. If we have an entering/leaving pair, all is okay
//
if (next->Entering() != curr->Entering()) {
curr = next + 1;
next = curr + 1;
break;
}
//
// Otherwise, they are duplicate, and just delete one
//
next = points.erase(next);
curr = next - 1;
}
if (curr == points.end()) break;
//
// The next point should be entering...
//
if (!curr->Entering()) {
//
// Point is out of sequence:
// Test solid just before this point
//
G4double s = curr->GetDistance();
G4ThreeVector p = p0 + s*v;
G4ThreeVector p1 = p - 10*kCarTolerance*v;
if (solid->Inside(p1) == kOutside) {
//
// We are missing an entrance point near the current
// point. Add one.
//
curr = points.insert(curr, G4GeomTestPoint( p, s, true ) );
++curr;
break;
}
//
// Test solid just after last point
//
if (curr != points.begin()) {
G4std::vector<G4GeomTestPoint>::iterator prev = curr - 1;
s = prev->GetDistance();
p = p0 + s*v;
p1 = p + 10*kCarTolerance*v;
if (solid->Inside(p1) == kOutside) {
//
// We are missing an entrance point near the previous
// point. Add one.
//
curr = points.insert(curr, G4GeomTestPoint( p, s, true ) );
++curr;
break;
}
}
//
// Oh oh. No solution. Delete the current point and complain.
//
logger->SolidProblem( solid, "Spurious exiting intersection point", p );
curr = points.erase(curr);
break;
}
//
// The following point should be leaving
//
if (next == points.end() || next->Entering() ) {
//
// But is missing. Check immediately after this point.
//
G4double s = curr->GetDistance();
G4ThreeVector p = p0 + s*v;
G4ThreeVector p1 = p + 10*kCarTolerance*v;
if (solid->Inside(p1) == kOutside) {
//
// We are missing an exit point near the current
// point. Add one.
//
curr = points.insert(next, G4GeomTestPoint( p, s, false ) );
break;
}
if (next != points.end()) {
//
// Check just before next point
//
s = next->GetDistance();
p = p0 + s*v;
p1 = p - 10*kCarTolerance*v;
if (solid->Inside(p1) == kOutside) {
//
// We are missing an exit point before the next
// point. Add one.
//
curr = points.insert(next, G4GeomTestPoint( p, s, false ) );
break;
}
}
//
// Oh oh. Hanging entering point. Delete and complain.
//
logger->SolidProblem( solid, "Spurious entering intersection point", p );
curr = points.erase(curr);
}
curr = next + 1;
} while( curr != points.end() );
//
// Double check
//
if (points.size()&1)
logger->SolidProblem( solid,
"Solid has odd number of intersection points", p0 );
return;
}
//
// Find intersections either in front or behind the point
//
void G4GeomTestSegment::FindSomePoints( G4GeomTestLogger *logger,
G4bool forward )
{
G4double sign = forward ? +1 : -1;
G4ThreeVector p(p0);
G4ThreeVector vSearch(sign*v);
G4double s(0);
G4bool entering;
//
// Look for nearest intersection point in the specified
// direction and return if there isn't one
//
G4double dist;
switch(solid->Inside(p)) {
case kInside:
dist = solid->DistanceToOut(p,vSearch);
if (dist >= kInfinity) {
logger->SolidProblem( solid,
"DistanceToOut(p,v) = kInfinity for point inside", p );
return;
}
s += sign*dist;
entering = false;
break;
case kOutside:
dist = solid->DistanceToIn(p,vSearch);
if (dist >= kInfinity) return;
s += sign*dist;
entering = true;
break;
case kSurface:
entering = (v.dot(solid->SurfaceNormal(p)) > 0);
break;
default:
logger->SolidProblem( solid,
"Inside returns illegal enumerated value", p );
return;
}
//
// Loop
//
// nzero = the number of consequtive zeros
//
G4int nzero=0;
for(;;) {
//
// Locate point
//
p = p0 + s*v;
//
// Record point
//
points.push_back( G4GeomTestPoint( p, s, entering==forward ) );
if (nzero > 2) {
//
// Oops. Infinite loop. Probably a geometry bug.
// We can give the solid a little help with a push
//
G4double push = 1E-6;
s += sign*push;
for(;;) {
p = p0 + s*v;
EInside inside = solid->Inside(p);
if (inside == kInside) {
entering = false;
break;
}
else if (inside == kOutside) {
entering = true;
break;
}
push = 2*push;
if (push > 0.1) {
logger->SolidProblem( solid,
"Push fails to fix geometry inconsistency", p );
return;
}
s += sign*push;
}
}
//
// Find next intersection
//
G4double dist;
if (entering) {
dist = solid->DistanceToOut(p,vSearch);
if (dist >= kInfinity) {
logger->SolidProblem( solid,
"DistanceToOut(p,v) = kInfinity for point inside", p );
return;
}
entering = false;
}
else {
dist = solid->DistanceToIn(p,vSearch);
if (dist >= kInfinity) return;
entering = true;
}
//
// Update s
//
if (dist <= 0) {
nzero++;
}
else {
nzero=0;
s += sign*dist;
}
}
}
@@ -0,0 +1,285 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4GeomTestStreamLogger.cc,v 1.4 2001/10/24 22:09:28 gcosmo Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// --------------------------------------------------------------------
// GEANT 4 class source file
//
// G4GeomTestStreamLogger
//
// Author: D.C.Williams, UCSC (davidw@scipp.ucsc.edu)
#include "G4GeomTestStreamLogger.hh"
#include "G4VSolid.hh"
#include "G4VPhysicalVolume.hh"
#include "g4std/iomanip"
#include "G4GeomTestOverlapList.hh"
#include "G4GeomTestOvershootList.hh"
//
// Constructor
//
G4GeomTestStreamLogger::G4GeomTestStreamLogger( G4std::ostream &o,
G4int theMaxPointsPerError )
: out(o), maxPointsPerError(theMaxPointsPerError)
{;}
//
// ::PrintPos
//
// Utility class for printing a 3 vector position
//
void G4GeomTestStreamLogger::PrintPos::Print( G4std::ostream &o ) const
{
o << G4std::setprecision(6) << G4std::setw(14) << p.x()/cm;
o << G4std::setprecision(6) << G4std::setw(14) << p.y()/cm;
o << G4std::setprecision(6) << G4std::setw(14) << p.z()/cm;
if (unit) o << " cm";
}
G4std::ostream &operator<<( G4std::ostream &o,
const G4GeomTestStreamLogger::PrintPos &p )
{
p.Print(o);
return o;
}
//
// ::VolumeNameAndCopy
//
// Utility class for printing a volume's name and copy number
//
void
G4GeomTestStreamLogger::VolumeNameAndCopy::Print( G4std::ostream &o ) const
{
o << volume->GetName() << "[" << volume->GetCopyNo() << "]";
}
G4std::ostream &operator<<( G4std::ostream &o,
const G4GeomTestStreamLogger::VolumeNameAndCopy &p )
{
p.Print(o);
return o;
}
//
// SolidProblem
//
void G4GeomTestStreamLogger::SolidProblem( const G4VSolid *solid,
const G4String &message,
const G4ThreeVector &point )
{
out << "GeomTest Error: SolidProblem\n"
<< " " << message << "\n"
<< " Solid name = " << solid->GetName() << "\n"
<< " Local position = " << PrintPos(point) << G4std::endl;
}
//
// NoProblem
//
void G4GeomTestStreamLogger::NoProblem( const G4String &message )
{
out << message << G4std::endl;
}
//
// OverlappingDaughters
//
void
G4GeomTestStreamLogger::OverlappingDaughters(const G4GeomTestOverlapList *list)
{
G4int n = list->NumError();
if (n <= 0) return;
out << "GeomTest Error: Overlapping daughter volumes\n"
<< " The volumes " << VolumeNameAndCopy(list->GetDaughter1())
<< " and " << VolumeNameAndCopy(list->GetDaughter2()) << ",\n"
<< " both daughters of volume " << VolumeNameAndCopy(list->GetMother())
<< ",\n"
<< " appear to overlap at the following " << (n>1 ? "points" : "point")
<< " in global coordinates:";
G4int nInterval, nStop;
if (n <= maxPointsPerError) {
out << "\n";
nInterval = 1;
nStop = n;
}
else {
out << " (list truncated)\n";
nInterval = n/maxPointsPerError;
nStop = maxPointsPerError*nInterval;
}
G4int i;
G4ThreeVector s1, s2;
PrintSegmentListHeader();
for(i=0;i<nStop;i+=nInterval) {
list->GetGlobalPoints( i, s1, s2 );
PrintSegmentListElement( s1, s2 );
}
out << " Which in the mother coordinate system " << IsAre(n) << ":\n";
PrintSegmentListHeader();
for(i=0;i<nStop;i+=nInterval) {
list->GetMotherPoints( i, s1, s2 );
PrintSegmentListElement( s1, s2 );
}
out << " Which in the coordinate system of "
<< VolumeNameAndCopy(list->GetDaughter1()) << " " << IsAre(n) << ":\n";
PrintSegmentListHeader();
for(i=0;i<nStop;i+=nInterval) {
list->GetDaught1Points( i, s1, s2 );
PrintSegmentListElement( s1, s2 );
}
out << " Which in the coordinate system of "
<< VolumeNameAndCopy(list->GetDaughter2()) << " " << IsAre(n) << ":\n";
PrintSegmentListHeader();
for(i=0;i<nStop;i+=nInterval) {
list->GetDaught2Points( i, s1, s2 );
PrintSegmentListElement( s1, s2 );
}
out << G4std::endl;
}
//
// OvershootingDaughter
//
void G4GeomTestStreamLogger::
OvershootingDaughter( const G4GeomTestOvershootList *list )
{
G4int n = list->NumError();
if (n <= 0) return;
out << "GeomTest Error: Overshooting daughter volume\n"
<< " The volume " << VolumeNameAndCopy(list->GetDaughter())
<< " appears to extend outside the mother volume "
<< VolumeNameAndCopy(list->GetMother()) << "\n"
<< " at the following " << (n>1 ? "points" : "point")
<< " in global coordinates:";
G4int nInterval, nStop;
if (n <= maxPointsPerError) {
out << "\n";
nInterval = 1;
nStop = n;
}
else {
out << " (list truncated)\n";
nInterval = n/maxPointsPerError;
nStop = maxPointsPerError*nInterval;
}
G4int i;
G4ThreeVector s1, s2;
PrintSegmentListHeader();
for(i=0;i<nStop;i+=nInterval) {
list->GetGlobalPoints( i, s1, s2 );
PrintSegmentListElement( s1, s2 );
}
out << " Which in the mother coordinate system " << IsAre(n) << ":\n";
PrintSegmentListHeader();
for(i=0;i<nStop;i+=nInterval) {
list->GetMotherPoints( i, s1, s2 );
PrintSegmentListElement( s1, s2 );
}
out << " Which in the coordinate system of "
<< VolumeNameAndCopy(list->GetDaughter()) << " " << IsAre(n) << ":\n";
PrintSegmentListHeader();
for(i=0;i<nStop;i+=nInterval) {
list->GetDaughtPoints( i, s1, s2 );
PrintSegmentListElement( s1, s2 );
}
out << G4std::endl;
}
//
// PrintSegmentListHeader (protected)
//
// Print out a header for a segment list
//
void G4GeomTestStreamLogger::PrintSegmentListHeader()
{
static const char *header =
" length (cm) ---------- start position (cm) ----------- ----------- end position (cm) ------------\n";
// .............| .............|.............|.............| .............|.............|.............|
// 1234 1234 123
out << header;
}
//
// PrintSegmentListElement (protected)
//
// Print out one segment value
//
void G4GeomTestStreamLogger::PrintSegmentListElement( const G4ThreeVector &s1,
const G4ThreeVector &s2 )
{
out << " " << G4std::setprecision(6) << G4std::setw(14)
<< (s1-s2).mag()/cm
<< " " << PrintPos(s1,false) << " " << PrintPos(s2,false) << "\n";
}
//
// IsAre (protected)
//
// Return a pointer to the string "is" if the argument
// is equal to 1, otherwise return a pointer to "are"
//
const char *G4GeomTestStreamLogger::IsAre( G4int n )
{
const char *is = "is";
const char *are = "are";
return n > 1 ? are : is;
}
@@ -0,0 +1,105 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4GeomTestVolPoint.cc,v 1.1 2001/10/17 13:00:00 gcosmo Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// --------------------------------------------------------------------
// GEANT 4 class source file
//
// G4GeomTestVolPoint
//
// Author: D.C.Williams, UCSC (davidw@scipp.ucsc.edu)
#include "G4GeomTestVolPoint.hh"
//
// Constructor (specific)
//
G4GeomTestVolPoint::G4GeomTestVolPoint( const G4ThreeVector &thePoint,
G4double theS,
G4bool isEntering,
G4int theDaughterIndex )
: G4GeomTestPoint( thePoint, theS, isEntering ),
daughterIndex(theDaughterIndex)
{;}
//
// Constructor (from base)
//
G4GeomTestVolPoint::G4GeomTestVolPoint( const G4GeomTestPoint &base,
G4int theDaughterIndex )
: G4GeomTestPoint( base ), daughterIndex(theDaughterIndex)
{;}
//
// Constructor (from base, with coordinate transformation)
//
G4GeomTestVolPoint::G4GeomTestVolPoint( const G4GeomTestPoint &base,
G4int theDaughterIndex,
const G4ThreeVector &translation,
const G4RotationMatrix *rotation )
: G4GeomTestPoint( base ), daughterIndex(theDaughterIndex)
{
//
// Rotate point
//
if (rotation)
p = rotation->inverse()*p - translation;
else
p = p - translation;
}
//
// Constructor (copy)
//
G4GeomTestVolPoint::G4GeomTestVolPoint( const G4GeomTestVolPoint &other )
: G4GeomTestPoint( other ), daughterIndex(other.daughterIndex)
{;}
//
// Constructor (default)
//
G4GeomTestVolPoint::G4GeomTestVolPoint()
: daughterIndex(-1)
{;}
//
// Destructor
//
G4GeomTestVolPoint::~G4GeomTestVolPoint() {;}
//
// Volume accessor
//
G4int G4GeomTestVolPoint::GetDaughterIndex() const
{
return daughterIndex;
}
@@ -0,0 +1,542 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4GeomTestVolume.cc,v 1.4 2001/10/24 22:09:28 gcosmo Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// --------------------------------------------------------------------
// GEANT 4 class source file
//
// G4GeomTestVolume
//
// Author: D.C.Williams, UCSC (davidw@scipp.ucsc.edu)
#include "G4GeomTestVolume.hh"
#include "G4GeomTestLogger.hh"
#include "G4GeomTestVolPoint.hh"
#include "G4GeomTestSegment.hh"
#include "G4VPhysicalVolume.hh"
#include "G4LogicalVolume.hh"
#include "G4VSolid.hh"
#include "g4std/vector"
#include "g4std/set"
#include "g4std/algorithm"
#include "g4std/iomanip"
//
// Constructor
//
G4GeomTestVolume::G4GeomTestVolume( const G4VPhysicalVolume *theTarget,
G4GeomTestLogger *theLogger,
G4double theTolerance )
: target(theTarget),
logger(theLogger),
tolerance(theTolerance),
extent(theTarget->GetLogicalVolume()->GetSolid()->GetExtent())
{;}
//
// Destructor
//
G4GeomTestVolume::~G4GeomTestVolume() {;}
//
// Get error tolerance
//
G4double G4GeomTestVolume::GetTolerance() const
{
return tolerance;
}
//
// Set error tolerance
//
void G4GeomTestVolume::SetTolerance(G4double val)
{
tolerance = val;
}
//
// TestCartGridXYZ
//
void G4GeomTestVolume::TestCartGridXYZ( G4int nx, G4int ny, G4int nz )
{
TestCartGridX( ny, nz );
TestCartGridY( nz, nx );
TestCartGridZ( nx, ny );
}
//
// TestCartGridX
//
void G4GeomTestVolume::TestCartGridX( G4int ny, G4int nz )
{
TestCartGrid( G4ThreeVector(0,1,0), G4ThreeVector(0,0,1),
G4ThreeVector(1,0,0), ny, nz );
}
//
// TestCartGridY
//
void G4GeomTestVolume::TestCartGridY( G4int nz, G4int nx )
{
TestCartGrid( G4ThreeVector(0,0,1), G4ThreeVector(1,0,0),
G4ThreeVector(0,1,0), nz, nx );
}
//
// TestCartGridZ
//
void G4GeomTestVolume::TestCartGridZ( G4int nx, G4int ny )
{
TestCartGrid( G4ThreeVector(1,0,0), G4ThreeVector(0,1,0),
G4ThreeVector(0,0,1), nx, ny );
}
//
// TestRecursiveCartGrid
//
void G4GeomTestVolume::TestRecursiveCartGrid( G4int nx, G4int ny, G4int nz )
{
//
// As long as we aren't a replica, test ourselves
//
if (!target->IsReplicated()) {
TestCartGridXYZ( nx, ny, nz );
ReportErrors();
}
//
// Loop over unique daughters
//
G4std::set<const G4LogicalVolume *> tested;
const G4LogicalVolume *logical = target->GetLogicalVolume();
G4int nDaughter = logical->GetNoDaughters();
G4int iDaughter;
for( iDaughter=0; iDaughter<nDaughter; ++iDaughter) {
const G4VPhysicalVolume *daughter =
logical->GetDaughter(iDaughter);
const G4LogicalVolume *daughterLogical =
daughter->GetLogicalVolume();
//
// Skip empty daughters
//
if (daughterLogical->GetNoDaughters() == 0) continue;
//
// Tested already?
//
G4std::pair<G4std::set<const G4LogicalVolume *>::iterator,G4bool>
there = tested.insert(daughterLogical);
if (!there.second) continue;
//
// Recurse
//
G4GeomTestVolume vTest( daughter, logger );
vTest.TestRecursiveCartGrid(nx,ny,nz);
}
}
//
// TestCylinder
//
void G4GeomTestVolume::TestCylinder( G4int nPhi, G4int nZ, G4int nRho,
G4double fracZ, G4double fracRho,
G4bool usePhi )
{
//
// Get size of our volume
//
G4double xMax = G4std::max(extent.GetXmax(),-extent.GetXmin());
G4double yMax = G4std::max(extent.GetYmax(),-extent.GetYmin());
G4double rhoMax = sqrt(xMax*xMax + yMax*yMax);
G4double zMax = extent.GetZmax();
G4double zMin = extent.GetZmin();
G4double zHalfLength = 0.5*(zMax-zMin);
G4double z0 = 0.5*(zMax+zMin);
//
// Loop over phi
//
G4double deltaPhi = 2*pi/G4double(nPhi);
G4double phi = 0;
G4int iPhi = nPhi;
if ((iPhi&1) == 0) iPhi++; // Also use odd number phi slices
do {
G4double cosPhi = cos(phi);
G4double sinPhi = sin(phi);
//
// Loop over rho
//
G4double rho = rhoMax;
G4int iRho = nRho;
do {
G4ThreeVector p(rho*cosPhi,rho*sinPhi,0);
static G4ThreeVector v(0,0,1);
TestOneLine( p, v );
if (usePhi) {
//
// Loop over z
//
G4ThreeVector v(sinPhi,-cosPhi,0);
G4double zScale = 1.0;
G4int iZ=nZ;
do {
p.setZ( z0 + zScale*zHalfLength );
TestOneLine(p,v);
p.setZ( z0 - zScale*zHalfLength );
TestOneLine(p,v);
} while( zScale *= fracZ, --iZ );
}
} while( rho *= fracRho, --iRho );
//
// Loop over z
//
G4ThreeVector p(0,0,0);
G4ThreeVector v(cosPhi,sinPhi,0);
G4double zScale = 1.0;
G4int iZ=nZ;
do {
p.setZ( z0 + zScale*zHalfLength );
TestOneLine(p,v);
p.setZ( z0 - zScale*zHalfLength );
TestOneLine(p,v);
} while( zScale *= fracZ, --iZ );
} while( phi += deltaPhi, --iPhi );
}
//
// TestCartGrid
//
void G4GeomTestVolume::TestCartGrid( const G4ThreeVector &theG1,
const G4ThreeVector &theG2,
const G4ThreeVector &theV,
G4int n1, G4int n2 )
{
if (n1 <= 0 || n2 <= 0)
G4Exception( "G4GeomTestVolume::TestCartGrid -- n1 and n2 must be >= 1" );
G4ThreeVector xMin( extent.GetXmin(), extent.GetYmin(),
extent.GetZmin() );
G4ThreeVector xMax( extent.GetXmax(), extent.GetYmax(),
extent.GetZmax() );
G4ThreeVector g1(theG1.unit());
G4ThreeVector g2(theG2.unit());
G4ThreeVector v(theV.unit());
G4double gMin1 = g1.dot(xMin);
G4double gMax1 = g1.dot(xMax);
G4double gMin2 = g2.dot(xMin);
G4double gMax2 = g2.dot(xMax);
G4double delta1 = (gMax1-gMin1)/G4double(n1);
G4double delta2 = (gMax2-gMin2)/G4double(n2);
G4int i1, i2;
for(i1=0;i1<=n1;++i1) {
G4ThreeVector p1 = (gMin1 + G4double(i1)*delta1)*g1;
for(i2=0;i2<=n2;++i2) {
G4ThreeVector p2 = (gMin2 + G4double(i2)*delta2)*g2;
TestOneLine( p1+p2, v );
}
}
}
//
// TestOneLine
//
// Test geometry consistency along a single line
//
void G4GeomTestVolume::TestOneLine( const G4ThreeVector &p,
const G4ThreeVector &v )
{
//
// Keep track of intersection points
//
G4std::vector<G4GeomTestVolPoint> points;
//
// Calculate intersections with the mother volume
//
G4GeomTestSegment targetSegment( target->GetLogicalVolume()->GetSolid(),
p, v, logger );
//
// Add them to our list
//
G4int n = targetSegment.GetNumberPoints();
G4int i;
for(i=0;i<n;++i) {
points.push_back( G4GeomTestVolPoint( targetSegment.GetPoint(i), -1 ) );
}
//
// Loop over daughter volumes
//
const G4LogicalVolume *logical = target->GetLogicalVolume();
G4int nDaughter = logical->GetNoDaughters();
G4int iDaughter;
for( iDaughter=0; iDaughter<nDaughter; ++iDaughter) {
const G4VPhysicalVolume *daughter =
logical->GetDaughter(iDaughter);
//
// Convert coordinates to daughter local coordinates
//
const G4RotationMatrix *rotation = daughter->GetFrameRotation();
const G4ThreeVector &translation = daughter->GetFrameTranslation();
G4ThreeVector pLocal = translation + p;
G4ThreeVector vLocal = v;
if (rotation) {
pLocal = (*rotation)*pLocal;
vLocal = (*rotation)*vLocal;
}
//
// Find intersections
//
G4GeomTestSegment
daughterSegment( daughter->GetLogicalVolume()->GetSolid(),
pLocal, vLocal, logger );
//
// Add them to the list
//
G4int n = daughterSegment.GetNumberPoints();
G4int i;
for(i=0;i<n;++i) {
points.push_back( G4GeomTestVolPoint( daughterSegment.GetPoint(i),
iDaughter, translation, rotation ) );
}
}
//
// Now sort the list of intersection points
//
G4std::sort( points.begin(), points.end() );
//
// Search for problems:
// 1. Overlap daughters will be indicated by intersecting
// points that lie within another daughter
// 2. Daughter extending outside the mother will be
// indicated by intersecting points outside the mother
//
// The search method is always looking forward when
// resolving discrepencies due to roundoff error. Once
// one instance of a daughter intersection is analyzed,
// it is removed from further consideration
//
n = points.size();
//
// Set true if this point has been analyzed
//
G4std::vector<G4bool> checked( n, false );
for(i=0;i<n;++i) {
if (checked[i]) continue;
G4int iDaug = points[i].GetDaughterIndex();
if (iDaug < 0) continue;
//
// Intersection found. Find matching pair.
//
G4double iS = points[i].GetDistance();
G4int j = i;
while(++j<n) {
if (iDaug == points[j].GetDaughterIndex()) break;
}
if (j>=n) {
//
// Unmatched? This shouldn't happen
//
logger->SolidProblem( logical->GetDaughter(iDaug)->
GetLogicalVolume()->GetSolid(),
"Unmatched intersection point",
points[i].GetPosition() );
continue;
}
checked[j] = true;
G4double jS = points[j].GetDistance();
//
// Otherwise, we could have a problem
//
G4int k = i;
while(++k<j) {
if (checked[k]) continue;
G4bool kEntering = points[k].Entering();
G4double kS = points[k].GetDistance();
//
// Problem found: catagorize
//
G4int kDaug = points[k].GetDaughterIndex();
if (kDaug < 0) {
//
// Ignore small overshoots if they are within tolerance
//
if (kS-iS < tolerance && kEntering ) continue;
if (jS-kS < tolerance && (!kEntering)) continue;
//
// We appear to extend outside the mother volume
//
G4std::map<G4long,G4GeomTestOvershootList>::iterator overshoot =
overshoots.find(iDaug);
if (overshoot == overshoots.end()) {
G4std::pair<G4std::map<G4long,G4GeomTestOvershootList>::iterator,G4bool>
result =
overshoots.insert( G4std::pair<const G4long,G4GeomTestOvershootList>
(iDaug,G4GeomTestOvershootList(target,iDaug)) );
assert(result.second);
overshoot = result.first;
}
if (kEntering)
(*overshoot).second.AddError( points[i].GetPosition(),
points[k].GetPosition() );
else
(*overshoot).second.AddError( points[k].GetPosition(),
points[j].GetPosition() );
}
else {
//
// Ignore small overlaps if they are within tolerance
//
if (kS-iS < tolerance && (!kEntering)) continue;
if (jS-kS < tolerance && kEntering ) continue;
//
// We appear to overlap with another daughter
//
G4long key = iDaug < kDaug ?
(iDaug*nDaughter + kDaug) : (kDaug*nDaughter + iDaug);
G4std::map<G4long,G4GeomTestOverlapList>::iterator overlap =
overlaps.find(key);
if (overlap == overlaps.end()) {
G4std::pair<G4std::map<G4long,G4GeomTestOverlapList>::iterator,G4bool>
result =
overlaps.insert( G4std::pair<const G4long,G4GeomTestOverlapList>
(key,G4GeomTestOverlapList(target,iDaug,kDaug)) );
assert(result.second);
overlap = result.first;
}
if (points[k].Entering())
(*overlap).second.AddError( points[k].GetPosition(),
points[j].GetPosition() );
else
(*overlap).second.AddError( points[i].GetPosition(),
points[k].GetPosition() );
}
}
}
}
//
// ReportErrors
//
void G4GeomTestVolume::ReportErrors()
{
//
// Report overshoots
//
if (overshoots.empty())
logger->NoProblem("GeomTest: no daughter volume extending outside mother detected.");
else {
G4std::map<G4long,G4GeomTestOvershootList>::iterator overshoot =
overshoots.begin();
while( overshoot != overshoots.end() ) {
logger->OvershootingDaughter( &(*overshoot).second );
++overshoot;
}
}
//
// Report overlaps
//
if (overlaps.empty())
logger->NoProblem("GeomTest: no overlapping daughters detected.");
else {
G4std::map<G4long,G4GeomTestOverlapList>::iterator overlap =
overlaps.begin();
while( overlap != overlaps.end() ) {
logger->OverlappingDaughters( &(*overlap).second );
++overlap;
}
}
}
//
// ClearErrors
//
void G4GeomTestVolume::ClearErrors()
{
overshoots.clear();
overlaps.clear();
}