00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "G3G4Interface.hh"
00032 #include "G3toG4.hh"
00033 #include "G3VolTable.hh"
00034 #include "G3toG4MakeSolid.hh"
00035 #include "G3Division.hh"
00036 #include "G4SystemOfUnits.hh"
00037 #include "G4VSolid.hh"
00038
00039 G4bool G3NegVolPars(G4double pars[], G4int *nparpt,
00040 G3VolTableEntry* vte, G3VolTableEntry* mvte, const char routine[]);
00041
00042 void PG4gsposp(G4String *tokens){
00043
00044 G3fillParams(tokens,PTgsposp);
00045
00046
00047 G4String name = Spar[0];
00048 G4String moth = Spar[1];
00049 G4String only = Spar[2];
00050 G4int num = Ipar[0];
00051 G4int irot = Ipar[1];
00052 G4int npar = Ipar[2];
00053
00054
00055
00056
00057
00058 G4double x = Rpar[0];
00059 G4double y = Rpar[1];
00060 G4double z = Rpar[2];
00061 G4double *pars = &Rpar[3];
00062
00063 G4gsposp(name, num, moth, x, y, z, irot, only, pars, npar);
00064 }
00065
00066 void G4ProcessDaughters(G3VolTableEntry* vte)
00067
00068
00069 {
00070 if (vte->HasNegPars()) {
00071 G4cerr << " Warning:" << G4endl;
00072 G4cerr << " G4ProcessDaughters: Ignored (vte has negative parameters)."
00073 << G4endl;
00074 }
00075 else {
00076 for (G4int i=0; i<vte->GetNoDaughters(); i++) {
00077
00078 G3VolTableEntry* dvte = vte->GetDaughter(i);
00079
00080 if (dvte->HasNegPars()) {
00081 if (dvte->GetDivision()) {
00082
00083
00084 dvte->GetDivision()->UpdateVTE();
00085 }
00086 else {
00087
00088 G4double* pars = dvte->GetRpar();
00089 G4int npar = dvte->GetNpar();
00090 G4bool negpars
00091 = G3NegVolPars(pars,&npar, dvte, vte, "GSPOS");
00092
00093 if (negpars) {
00094 G4String text = "G3NegVolPars still returns negative parameters!";
00095 G4Exception("G4ProcessDaughters()", "G3toG40019",
00096 FatalException, text);
00097 return;
00098 }
00099
00100
00101 G4bool hasNegPars;
00102 G4bool deferred;
00103 G4bool okAxis[3];
00104 G4VSolid* solid
00105 = G3toG4MakeSolid(dvte->GetName(), dvte->GetShape(), pars, npar,
00106 hasNegPars, deferred, okAxis);
00107 if (hasNegPars) {
00108 G4String text = "G3toG4MakeSolid still returns negative parameters!";
00109 G4Exception("G4ProcessDaughters()", "G3toG40020",
00110 FatalException, text);
00111 return;
00112 }
00113
00114
00115 dvte->SetNRpar(npar, pars);
00116 dvte->SetSolid(solid);
00117 dvte->SetHasNegPars(hasNegPars);
00118 }
00119
00120
00121 G4ProcessDaughters(dvte);
00122 }
00123 }
00124 }
00125 }
00126
00127 void G4CloneDaughters(G3VolTableEntry* vte, G3VolTableEntry* vteClone)
00128
00129
00130
00131 {
00132 G4int nofDaughters = vte->GetNoDaughters();
00133 if (nofDaughters>0)
00134 for (G4int id=0; id<nofDaughters; id++) {
00135 G3VolTableEntry* dvte = vte->GetDaughter(id);
00136
00137 if (dvte->HasNegPars() || dvte->GetDivision()){
00138
00139
00140
00141
00142 G3VolTableEntry* dvteMaster = dvte->GetMasterClone();
00143
00144
00145 G4int cloneNo = dvteMaster->GetNoClones();
00146 char index[5]; sprintf(index,"%d",cloneNo);
00147 G4String newName = dvteMaster->GetName();
00148 newName.append(gSeparator); newName = newName + index;
00149
00150
00151 G4String dvteShape = dvte->GetShape();
00152 G4double* dvteRpar = dvte->GetRpar();
00153 G4int dvteNpar = dvte->GetNpar();
00154 G4int dvteNmed = dvte->GetNmed();
00155 G4bool hasNegPars = dvte->HasNegPars();
00156 G3VolTableEntry* dvteClone
00157 = new G3VolTableEntry(newName, dvteShape, dvteRpar, dvteNpar,
00158 dvteNmed, 0, hasNegPars);
00159
00160
00161 G3Vol.PutVTE(dvteClone);
00162 dvteMaster->AddClone(dvteClone);
00163
00164
00165 vteClone->AddDaughter(dvteClone);
00166 dvteClone->AddMother(vteClone);
00167
00168
00169 G4int nofPositions = dvte->NPCopies();
00170 for (G4int ip=0; ip<nofPositions; ip++)
00171 dvteClone->AddG3Pos(dvte->GetG3PosCopy(ip));
00172
00173
00174 G3Division* dvteDivision = dvte->GetDivision();
00175 if (dvteDivision) {
00176 G3Division* dvteCloneDivision
00177 = new G3Division(dvteClone, vteClone, *dvteDivision);
00178 dvteClone->SetDivision(dvteCloneDivision);
00179 dvteCloneDivision->UpdateVTE();
00180 }
00181
00182
00183 G4CloneDaughters(dvte, dvteClone);
00184 }
00185 else {
00186
00187 vteClone->AddDaughter(dvte);
00188 dvte->AddMother(vteClone);
00189 }
00190 }
00191 }
00192
00193 void G4CreateCloneVTE(G3VolTableEntry* vte, G3VolTableEntry* mvte,
00194 G4double pars[], G4int npar, G4int num,
00195 G4double x, G4double y, G4double z, G4int irot, G4String vonly)
00196
00197
00198
00199 {
00200
00201 G4ThreeVector* offset = new G4ThreeVector(x*cm, y*cm, z*cm);
00202 G3Pos* aG3Pos = new G3Pos(mvte->GetName(), num, offset, irot, vonly);
00203
00204
00205 for (G4int i=0; i<mvte->GetNoClones(); i++) {
00206
00207
00208 G3VolTableEntry* mvteClone = mvte->GetClone(i);
00209
00210 G4String tmpName = "TRY";
00211 G4String vteShape = vte->GetShape();
00212 G3VolTableEntry* vteClone
00213 = new G3VolTableEntry(tmpName, vteShape, pars, npar, vte->GetNmed(),
00214 0, true);
00215
00216
00217
00218 G4double* clonePars = vteClone->GetRpar();
00219 G4int cloneNpar = vteClone->GetNpar();
00220 G4bool negpars
00221 = G3NegVolPars(clonePars, &cloneNpar, vteClone, mvteClone, "GSPOS");
00222 vteClone->SetHasNegPars(negpars);
00223
00224 G3VolTableEntry* vteSameClone = 0;
00225 G4VSolid* solid = 0;
00226 if (!negpars) {
00227
00228 for (G4int ic=0; ic<vte->GetNoClones(); ic++) {
00229 G3VolTableEntry* checkClone = vte->GetClone(ic);
00230 G4int checkNpar = checkClone->GetNpar();
00231 G4double* checkPars = checkClone->GetRpar();
00232
00233 G4bool isSame;
00234 if (checkNpar != cloneNpar)
00235 isSame = false;
00236 else {
00237 isSame = true;
00238 for (G4int ip=0; ip<cloneNpar; ip++)
00239 if (checkPars[ip] != clonePars[ip]) {
00240 isSame = false;
00241 break;
00242 }
00243 }
00244 if (isSame) { vteSameClone = checkClone; break; }
00245 }
00246
00247 if (vteSameClone) {
00248 delete vteClone;
00249
00250
00251 vteSameClone->AddG3Pos(aG3Pos);
00252 mvteClone->AddDaughter(vteSameClone);
00253 vteSameClone->AddMother(mvteClone);
00254 }
00255 else {
00256
00257 G4bool hasNegPars;
00258 G4bool deferred;
00259 G4bool okAxis[3];
00260 G4String vteName = vte->GetName();
00261 G4String cloneShape = vteClone->GetShape();
00262 solid = G3toG4MakeSolid(vteName, cloneShape, clonePars, cloneNpar,
00263 hasNegPars, deferred, okAxis);
00264 }
00265 }
00266
00267 if ( negpars || !(vteSameClone)) {
00268
00269 G4int cloneNo = vte->GetNoClones();
00270 char index[5]; sprintf(index,"%d",cloneNo);
00271 G4String newName = vte->GetName();
00272 newName.append(gSeparator); newName = newName + index;
00273
00274
00275 vteClone->SetName(newName);
00276 vteClone->SetSolid(solid);
00277 vteClone->SetHasNegPars(negpars);
00278
00279
00280 G3Vol.PutVTE(vteClone);
00281 vte->AddClone(vteClone);
00282
00283
00284 vteClone->AddG3Pos(aG3Pos);
00285 mvteClone->AddDaughter(vteClone);
00286 vteClone->AddMother(mvteClone);
00287
00288
00289 G4CloneDaughters(vte, vteClone);
00290
00291
00292 if (!negpars) G4ProcessDaughters(vteClone);
00293 }
00294 }
00295 }
00296
00297 void G4gsposp(G4String vname, G4int num, G4String vmoth, G4double x,
00298 G4double y, G4double z, G4int irot, G4String vonly,
00299 G4double pars[], G4int npar)
00300 {
00301
00302 G3VolTableEntry* vte = G3Vol.GetVTE(vname);
00303 G3VolTableEntry* mvte = G3Vol.GetVTE(vmoth);
00304
00305 if (vte == 0) {
00306 G4String err_message1 = "G4gsposp: '" + vname + "' has no VolTableEntry";
00307 G4Exception("G4psposp()", "G3toG40021", FatalException, err_message1);
00308 return;
00309 }
00310 if (mvte == 0) {
00311 G4String err_message2 = "G4gsposp: '" + vmoth + "' has no VolTableEntry";
00312 G4Exception("G4psposp()", "G3toG40022", FatalException, err_message2);
00313 return;
00314 }
00315 else {
00316
00317
00318
00319 G4CreateCloneVTE(vte, mvte, pars, npar, num, x, y, z, irot, vonly);
00320 }
00321 }