Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // 27 // 28 // by I.Hrivnacova, 13.10.99 29 30 #include "G3G4Interface.hh" 31 #include "G3toG4.hh" 32 #include "G3VolTable.hh" 33 #include "G3toG4MakeSolid.hh" 34 #include "G3Division.hh" 35 #include "G4SystemOfUnits.hh" 36 #include "G4VSolid.hh" 37 38 G4bool G3NegVolPars(G4double pars[], G4int *nparpt, 39 G3VolTableEntry* vte, G3VolTableEntry* mvte, const char routine[]); 40 41 void PG4gsposp(G4String *tokens){ 42 // fill the parameter containers 43 G3fillParams(tokens,PTgsposp); 44 45 // interpret the parameters 46 G4String name = Spar[0]; 47 G4String moth = Spar[1]; 48 G4String only = Spar[2]; 49 G4int num = Ipar[0]; 50 G4int irot = Ipar[1]; 51 G4int npar = Ipar[2]; 52 // all parameters are passed to G4gsxxx methods 53 // in G3 default units 54 //G4double x = Rpar[0]*cm; 55 //G4double y = Rpar[1]*cm; 56 //G4double z = Rpar[2]*cm; 57 G4double x = Rpar[0]; 58 G4double y = Rpar[1]; 59 G4double z = Rpar[2]; 60 G4double *pars = &Rpar[3]; 61 62 G4gsposp(name, num, moth, x, y, z, irot, only, pars, npar); 63 } 64 65 void G4ProcessDaughters(G3VolTableEntry* vte) 66 // restore negative volume parameters and create solid for all 67 // vte daughters 68 { 69 if (vte->HasNegPars()) { 70 G4cerr << " Warning:" << G4endl; 71 G4cerr << " G4ProcessDaughters: Ignored (vte has negative parameters)." 72 << G4endl; 73 } 74 else { 75 for (G4int i=0; i<vte->GetNoDaughters(); i++) { 76 77 G3VolTableEntry* dvte = vte->GetDaughter(i); 78 79 if (dvte->HasNegPars()) { 80 if (dvte->GetDivision()) { 81 // call division method for creating solid and updating 82 // dvte parameters 83 dvte->GetDivision()->UpdateVTE(); 84 } 85 else { 86 // update negative parameters 87 G4double* pars = dvte->GetRpar(); 88 G4int npar = dvte->GetNpar(); 89 G4bool negpars 90 = G3NegVolPars(pars,&npar, dvte, vte, "GSPOS"); 91 92 if (negpars) { 93 G4String text = "G3NegVolPars still returns negative parameters!"; 94 G4Exception("G4ProcessDaughters()", "G3toG40019", 95 FatalException, text); 96 return; 97 } 98 99 // create solid 100 G4bool hasNegPars; 101 G4bool deferred; 102 G4bool okAxis[3]; 103 G4VSolid* solid 104 = G3toG4MakeSolid(dvte->GetName(), dvte->GetShape(), pars, npar, 105 hasNegPars, deferred, okAxis); 106 if (hasNegPars) { 107 G4String text = "G3toG4MakeSolid still returns negative parameters!"; 108 G4Exception("G4ProcessDaughters()", "G3toG40020", 109 FatalException, text); 110 return; 111 } 112 113 // update dvte 114 dvte->SetNRpar(npar, pars); 115 dvte->SetSolid(solid); 116 dvte->SetHasNegPars(hasNegPars); 117 } 118 119 // process daughters 120 G4ProcessDaughters(dvte); 121 } 122 } 123 } 124 } 125 126 void G4CloneDaughters(G3VolTableEntry* vte, G3VolTableEntry* vteClone) 127 // copy vte daughters to vteClone 128 // (in case of daughters with negative parameters 129 // or with divisions new clone copies have to be created) 130 { 131 G4int nofDaughters = vte->GetNoDaughters(); 132 if (nofDaughters>0) 133 for (G4int id=0; id<nofDaughters; id++) { 134 G3VolTableEntry* dvte = vte->GetDaughter(id); 135 136 if (dvte->HasNegPars() || dvte->GetDivision()){ 137 // create new dvteClone with Position/Division 138 // and set it to vteClone 139 140 // get master of dvte 141 G3VolTableEntry* dvteMaster = dvte->GetMasterClone(); 142 143 // generate vteClone name 144 G4int cloneNo = dvteMaster->GetNoClones(); 145 G4String newName = dvteMaster->GetName(); 146 newName += gSeparator; 147 newName = newName + std::to_string(cloneNo); 148 149 // create dvteClone 150 G4String dvteShape = dvte->GetShape(); 151 G4double* dvteRpar = dvte->GetRpar(); 152 G4int dvteNpar = dvte->GetNpar(); 153 G4int dvteNmed = dvte->GetNmed(); 154 G4bool hasNegPars = dvte->HasNegPars(); 155 G3VolTableEntry* dvteClone 156 = new G3VolTableEntry(newName, dvteShape, dvteRpar, dvteNpar, 157 dvteNmed, 0, hasNegPars); 158 159 // let dvte master and vol table know about it 160 G3Vol.PutVTE(dvteClone); 161 dvteMaster->AddClone(dvteClone); 162 163 // set mother daughter 164 vteClone->AddDaughter(dvteClone); 165 dvteClone->AddMother(vteClone); 166 167 // copy positions 168 G4int nofPositions = dvte->NPCopies(); 169 for (G4int ip=0; ip<nofPositions; ip++) 170 dvteClone->AddG3Pos(dvte->GetG3PosCopy(ip)); 171 172 // copy division 173 G3Division* dvteDivision = dvte->GetDivision(); 174 if (dvteDivision) { 175 G3Division* dvteCloneDivision 176 = new G3Division(dvteClone, vteClone, *dvteDivision); 177 dvteClone->SetDivision(dvteCloneDivision); 178 dvteCloneDivision->UpdateVTE(); 179 } 180 181 // clone daughters recursively 182 G4CloneDaughters(dvte, dvteClone); 183 } 184 else { 185 // set dvte to vteClone 186 vteClone->AddDaughter(dvte); 187 dvte->AddMother(vteClone); 188 } 189 } 190 } 191 192 void G4CreateCloneVTE(G3VolTableEntry* vte, G3VolTableEntry* mvte, 193 G4double pars[], G4int npar, G4int num, 194 G4double x, G4double y, G4double z, G4int irot, G4String vonly) 195 // 196 // create a new vte clone copy for each mother 197 // and derive its parameters from the mother if possible 198 { 199 // create a G3Pos 200 G4ThreeVector* offset = new G4ThreeVector(x*cm, y*cm, z*cm); 201 G3Pos* aG3Pos = new G3Pos(mvte->GetName(), num, offset, irot, vonly); 202 203 // loop over all mothers 204 for (G4int i=0; i<mvte->GetNoClones(); i++) { 205 // mvte was retrieved from its "master" name 206 // -> there is no need to call GetMasterClone() 207 G3VolTableEntry* mvteClone = mvte->GetClone(i); 208 209 G4String tmpName = "TRY"; 210 G4String vteShape = vte->GetShape(); 211 G3VolTableEntry* vteClone 212 = new G3VolTableEntry(tmpName, vteShape, pars, npar, vte->GetNmed(), 213 0, true); 214 215 // negative parameters will be updated only 216 // for vteClone, pars are unchanged 217 G4double* clonePars = vteClone->GetRpar(); 218 G4int cloneNpar = vteClone->GetNpar(); 219 G4bool negpars 220 = G3NegVolPars(clonePars, &cloneNpar, vteClone, mvteClone, "GSPOS"); 221 vteClone->SetHasNegPars(negpars); 222 223 G3VolTableEntry* vteSameClone = 0; 224 G4VSolid* solid = 0; 225 if (!negpars) { 226 // check if vteClone with the same parameters exist 227 for (G4int ic=0; ic<vte->GetNoClones(); ic++) { 228 G3VolTableEntry* checkClone = vte->GetClone(ic); 229 G4int checkNpar = checkClone->GetNpar(); 230 G4double* checkPars = checkClone->GetRpar(); 231 232 G4bool isSame; 233 if (checkNpar != cloneNpar) 234 isSame = false; 235 else { 236 isSame = true; 237 for (G4int ip=0; ip<cloneNpar; ip++) 238 if (checkPars[ip] != clonePars[ip]) { 239 isSame = false; 240 break; 241 } 242 } 243 if (isSame) { vteSameClone = checkClone; break; } 244 } 245 246 if (vteSameClone) { 247 delete vteClone; 248 249 // add aG3Pos to the vteClone 250 vteSameClone->AddG3Pos(aG3Pos); 251 mvteClone->AddDaughter(vteSameClone); 252 vteSameClone->AddMother(mvteClone); 253 } 254 else { 255 // create the solid 256 G4bool hasNegPars; 257 G4bool deferred; 258 G4bool okAxis[3]; 259 G4String vteName = vte->GetName(); 260 G4String cloneShape = vteClone->GetShape(); 261 solid = G3toG4MakeSolid(vteName, cloneShape, clonePars, cloneNpar, 262 hasNegPars, deferred, okAxis); 263 } 264 } 265 266 if ( negpars || !(vteSameClone)) { 267 // generate vteClone name 268 G4int cloneNo = vte->GetNoClones(); 269 G4String newName = vte->GetName(); 270 newName += gSeparator; 271 newName = newName + std::to_string(cloneNo); 272 273 // update vteClone 274 vteClone->SetName(newName); 275 vteClone->SetSolid(solid); 276 vteClone->SetHasNegPars(negpars); 277 278 // let vte and vol table know about it 279 G3Vol.PutVTE(vteClone); 280 vte->AddClone(vteClone); 281 282 // add aG3Pos to the vteClone 283 vteClone->AddG3Pos(aG3Pos); 284 mvteClone->AddDaughter(vteClone); 285 vteClone->AddMother(mvteClone); 286 287 // copy all daughters 288 G4CloneDaughters(vte, vteClone); 289 290 // retrieve daughters parameters 291 if (!negpars) G4ProcessDaughters(vteClone); 292 } 293 } 294 } 295 296 void G4gsposp(G4String vname, G4int num, G4String vmoth, G4double x, 297 G4double y, G4double z, G4int irot, G4String vonly, 298 G4double pars[], G4int npar) 299 { 300 // find VTEs 301 G3VolTableEntry* vte = G3Vol.GetVTE(vname); 302 G3VolTableEntry* mvte = G3Vol.GetVTE(vmoth); 303 304 if (vte == 0) { 305 G4String err_message1 = "G4gsposp: '" + vname + "' has no VolTableEntry"; 306 G4Exception("G4psposp()", "G3toG40021", FatalException, err_message1); 307 return; 308 } 309 if (mvte == 0) { 310 G4String err_message2 = "G4gsposp: '" + vmoth + "' has no VolTableEntry"; 311 G4Exception("G4psposp()", "G3toG40022", FatalException, err_message2); 312 return; 313 } 314 else { 315 // a new vte clone copy is created for each mother (clone copy) 316 // and its parameters are derived from it if possible 317 318 G4CreateCloneVTE(vte, mvte, pars, npar, num, x, y, z, irot, vonly); 319 } 320 } 321