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