Files
geant4/source/g3tog4/src/G4gsposp.cc
T
2016-06-09 15:16:48 +02:00

317 lines
11 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * 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. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4gsposp.cc,v 1.16 2006/06/29 18:14:44 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
//
// by I.Hrivnacova, 13.10.99
#include "G3G4Interface.hh"
#include "G3toG4.hh"
#include "G3VolTable.hh"
#include "G3toG4MakeSolid.hh"
#include "G3Division.hh"
#include "G4VSolid.hh"
G4bool G3NegVolPars(G4double pars[], G4int *nparpt,
G3VolTableEntry* vte, G3VolTableEntry* mvte, const char routine[]);
void PG4gsposp(G4String tokens[]){
// fill the parameter containers
G3fillParams(tokens,PTgsposp);
// interpret the parameters
G4String name = Spar[0];
G4String moth = Spar[1];
G4String only = Spar[2];
G4int num = Ipar[0];
G4int irot = Ipar[1];
G4int npar = Ipar[2];
// all parameters are passed to G4gsxxx methods
// in G3 default units
//G4double x = Rpar[0]*cm;
//G4double y = Rpar[1]*cm;
//G4double z = Rpar[2]*cm;
G4double x = Rpar[0];
G4double y = Rpar[1];
G4double z = Rpar[2];
G4double *pars = &Rpar[3];
G4gsposp(name, num, moth, x, y, z, irot, only, pars, npar);
}
void G4ProcessDaughters(G3VolTableEntry* vte)
// restore negative volume parameters and create solid for all
// vte daughters
{
if (vte->HasNegPars()) {
G4cerr << " Warning:" << G4endl;
G4cerr << " G4ProcessDaughters: Ignored (vte has negative parameters)."
<< G4endl;
}
else {
for (G4int i=0; i<vte->GetNoDaughters(); i++) {
G3VolTableEntry* dvte = vte->GetDaughter(i);
if (dvte->HasNegPars()) {
if (dvte->GetDivision()) {
// call division method for creating solid and updating
// dvte parameters
dvte->GetDivision()->UpdateVTE();
}
else {
// update negative parameters
G4double* pars = dvte->GetRpar();
G4int npar = dvte->GetNpar();
G4bool negpars
= G3NegVolPars(pars,&npar, dvte, vte, "GSPOS");
if (negpars) {
G4String text = " G4ProcessDaughter:\n";
text = text + " G3NegVolPars still returns negative parameters!";
G4Exception(text);
}
// create solid
G4bool hasNegPars;
G4bool deferred;
G4bool okAxis[3];
G4VSolid* solid
= G3toG4MakeSolid(dvte->GetName(), dvte->GetShape(), pars, npar,
hasNegPars, deferred, okAxis);
if (hasNegPars) {
G4String text = " G4ProcessDaughter:\n";
text = text + " G3toG4MakeSolid still returns negative parameters!";
G4Exception(text);
}
// update dvte
dvte->SetNRpar(npar, pars);
dvte->SetSolid(solid);
dvte->SetHasNegPars(hasNegPars);
}
// process daughters
G4ProcessDaughters(dvte);
}
}
}
}
void G4CloneDaughters(G3VolTableEntry* vte, G3VolTableEntry* vteClone)
// copy vte daughters to vteClone
// (in case of daughters with negative parameters
// or with divisions new clone copies have to be created)
{
G4int nofDaughters = vte->GetNoDaughters();
if (nofDaughters>0)
for (G4int id=0; id<nofDaughters; id++) {
G3VolTableEntry* dvte = vte->GetDaughter(id);
if (dvte->HasNegPars() || dvte->GetDivision()){
// create new dvteClone with Position/Division
// and set it to vteClone
// get master of dvte
G3VolTableEntry* dvteMaster = dvte->GetMasterClone();
// generate vteClone name
G4int cloneNo = dvteMaster->GetNoClones();
char index[5]; sprintf(index,"%d",cloneNo);
G4String newName = dvteMaster->GetName();
newName.append(gSeparator); newName = newName + index;
// create dvteClone
G4String dvteShape = dvte->GetShape();
G4double* dvteRpar = dvte->GetRpar();
G4int dvteNpar = dvte->GetNpar();
G4int dvteNmed = dvte->GetNmed();
G4bool hasNegPars = dvte->HasNegPars();
G3VolTableEntry* dvteClone
= new G3VolTableEntry(newName, dvteShape, dvteRpar, dvteNpar,
dvteNmed, 0, hasNegPars);
// let dvte master and vol table know about it
G3Vol.PutVTE(dvteClone);
dvteMaster->AddClone(dvteClone);
// set mother daughter
vteClone->AddDaughter(dvteClone);
dvteClone->AddMother(vteClone);
// copy positions
G4int nofPositions = dvte->NPCopies();
for (G4int ip=0; ip<nofPositions; ip++)
dvteClone->AddG3Pos(dvte->GetG3PosCopy(ip));
// copy division
G3Division* dvteDivision = dvte->GetDivision();
if (dvteDivision) {
G3Division* dvteCloneDivision
= new G3Division(dvteClone, vteClone, *dvteDivision);
dvteClone->SetDivision(dvteCloneDivision);
dvteCloneDivision->UpdateVTE();
}
// clone daughters recursively
G4CloneDaughters(dvte, dvteClone);
}
else {
// set dvte to vteClone
vteClone->AddDaughter(dvte);
dvte->AddMother(vteClone);
}
}
}
void G4CreateCloneVTE(G3VolTableEntry* vte, G3VolTableEntry* mvte,
G4double pars[], G4int npar, G4int num,
G4double x, G4double y, G4double z, G4int irot, G4String vonly)
//
// create a new vte clone copy for each mother
// and derive its parameters from the mother if possible
{
// create a G3Pos
G4ThreeVector* offset = new G4ThreeVector(x*cm, y*cm, z*cm);
G3Pos* aG3Pos = new G3Pos(mvte->GetName(), num, offset, irot, vonly);
// loop over all mothers
for (G4int i=0; i<mvte->GetNoClones(); i++) {
// mvte was retrieved from its "master" name
// -> there is no need to call GetMasterClone()
G3VolTableEntry* mvteClone = mvte->GetClone(i);
G4String tmpName = "TRY";
G4String vteShape = vte->GetShape();
G3VolTableEntry* vteClone
= new G3VolTableEntry(tmpName, vteShape, pars, npar, vte->GetNmed(),
0, true);
// negative parameters will be updated only
// for vteClone, pars are unchanged
G4double* clonePars = vteClone->GetRpar();
G4int cloneNpar = vteClone->GetNpar();
G4bool negpars
= G3NegVolPars(clonePars, &cloneNpar, vteClone, mvteClone, "GSPOS");
vteClone->SetHasNegPars(negpars);
G3VolTableEntry* vteSameClone = 0;
G4VSolid* solid = 0;
if (!negpars) {
// check if vteClone with the same parameters exist
for (G4int ic=0; ic<vte->GetNoClones(); ic++) {
G3VolTableEntry* checkClone = vte->GetClone(ic);
G4int checkNpar = checkClone->GetNpar();
G4double* checkPars = checkClone->GetRpar();
G4bool isSame;
if (checkNpar != cloneNpar)
isSame = false;
else {
isSame = true;
for (G4int ip=0; ip<cloneNpar; ip++)
if (checkPars[ip] != clonePars[ip]) {
isSame = false;
break;
}
}
if (isSame) vteSameClone = checkClone;
break;
}
if (vteSameClone) {
delete vteClone;
// add aG3Pos to the vteClone
vteSameClone->AddG3Pos(aG3Pos);
mvteClone->AddDaughter(vteSameClone);
vteSameClone->AddMother(mvteClone);
}
else {
// create the solid
G4bool hasNegPars;
G4bool deferred;
G4bool okAxis[3];
G4String vteName = vte->GetName();
G4String cloneShape = vteClone->GetShape();
solid = G3toG4MakeSolid(vteName, cloneShape, clonePars, cloneNpar,
hasNegPars, deferred, okAxis);
}
}
if ( negpars || !(vteSameClone)) {
// generate vteClone name
G4int cloneNo = vte->GetNoClones();
char index[5]; sprintf(index,"%d",cloneNo);
G4String newName = vte->GetName();
newName.append(gSeparator); newName = newName + index;
// update vteClone
vteClone->SetName(newName);
vteClone->SetSolid(solid);
vteClone->SetHasNegPars(negpars);
// let vte and vol table know about it
G3Vol.PutVTE(vteClone);
vte->AddClone(vteClone);
// add aG3Pos to the vteClone
vteClone->AddG3Pos(aG3Pos);
mvteClone->AddDaughter(vteClone);
vteClone->AddMother(mvteClone);
// copy all daughters
G4CloneDaughters(vte, vteClone);
// retrieve daughters parameters
if (!negpars) G4ProcessDaughters(vteClone);
}
}
}
void G4gsposp(G4String vname, G4int num, G4String vmoth, G4double x,
G4double y, G4double z, G4int irot, G4String vonly,
G4double pars[], G4int npar)
{
// find VTEs
G3VolTableEntry* vte = G3Vol.GetVTE(vname);
G3VolTableEntry* mvte = G3Vol.GetVTE(vmoth);
if (vte == 0) {
G4Exception("G4gsposp: '" + vname + "' has no VolTableEntry");
}
if (mvte == 0) {
G4Exception("G4gsposp: '" + vmoth + "' has no VolTableEntry");
}
else {
// a new vte clone copy is created for each mother (clone copy)
// and its parameters are derived from it if possible
G4CreateCloneVTE(vte, mvte, pars, npar, num, x, y, z, irot, vonly);
}
}