43 #ifndef G3G4_NO_REFLECTION
56 fNofDivisions(nofDivisions),
76 fType = division.fType;
77 fNofDivisions = division.fNofDivisions;
78 fIAxis = division.fIAxis;
79 fNmed = division.fNmed;
81 fStep = division.fStep;
102 if (fNmed == 0) fNmed = fMVTE->
GetNmed();
110 if (fType ==
kDvn) envVTE = Dvn();
111 else if (fType ==
kDvn2) envVTE = Dvn2();
112 else if (fType ==
kDvt) envVTE = Dvt();
113 else if (fType ==
kDvt2) envVTE = Dvt2();
135 if (shape ==
"PARA") {
141 for (
G4int i=0; i<fNofDivisions; i++) {
143 position[fIAxis-1] = fLowRange + fWidth/2. + i*fWidth;
144 if (position.
y()!=0.)
147 #ifndef G3G4_NO_REFLECTION
162 G4cout <<
"Create G4PVReplica name " << name <<
" logical volume name "
163 << lv->
GetName() <<
" mother logical volme name "
164 << mlv->
GetName() <<
" axis " << fAxis <<
" ndivisions "
165 << fNofDivisions <<
" width " << fWidth <<
" Offset "
169 #ifndef G3G4_NO_REFLECTION
171 ->
Replicate(name, lv, mlv, fAxis, fNofDivisions, fWidth, fOffset);
174 new G4PVReplica(name, lv, mlv, fAxis, fNofDivisions, fWidth, fOffset);
183 G4String err_message =
"G3Division::" + where +
" for "
184 + what +
" is not implemented";
185 G4Exception(
"G3Division::Exception()",
"G3toG40004",
190 void G3Division::SetRangeAndAxis()
203 default:
G4Exception(
"G3Division::SetRangeAndAxis()",
"G3toG40005",
207 if ( shape ==
"BOX" ) {
208 fHighRange = Rpar[fIAxis-1]*
cm;
209 fLowRange = -fHighRange;
211 else if ( shape ==
"TRD1" ) {
213 fHighRange =
std::max(Rpar[0]*
cm, Rpar[1]*cm);
215 else if( fIAxis == 2) {
216 fHighRange = Rpar[2]*
cm;
218 else if( fIAxis == 3) {
219 fHighRange = Rpar[3]*
cm;
221 fLowRange = - fHighRange;
223 else if ( shape ==
"TRD2" ) {
225 fHighRange =
std::max(Rpar[0]*
cm, Rpar[1]*cm);
227 else if( fIAxis == 2) {
228 fHighRange =
std::max(Rpar[2]*
cm, Rpar[3]*cm);
230 else if( fIAxis == 3) {
231 fHighRange = Rpar[4]*
cm;
234 else if ( shape ==
"TRAP" ) {
235 if ( fIAxis == 3 ) fHighRange = Rpar[0]*
cm;
236 else fHighRange = 0.;
237 fLowRange = -fHighRange;
239 else if ( shape ==
"TUBE" ) {
241 fHighRange = Rpar[1]*
cm;
242 fLowRange = Rpar[0]*
cm;
245 else if( fIAxis == 2) {
246 fHighRange = 360.*
deg;
250 else if( fIAxis == 3) {
251 fHighRange = Rpar[2]*
cm;
252 fLowRange = -fHighRange;
255 else if ( shape ==
"TUBS" ) {
257 fHighRange = Rpar[1]*
cm;
258 fLowRange = Rpar[0]*
cm;
261 else if( fIAxis == 2) {
263 fLowRange = Rpar[3]*
deg;
264 fHighRange = Rpar[4]*deg - fLowRange;
265 if ( Rpar[4]*deg <= fLowRange )fHighRange = fHighRange + 360.*
deg;
266 fHighRange = fHighRange + fLowRange;
269 else if( fIAxis == 3) {
270 fHighRange = Rpar[2]*
cm;
271 fLowRange = -fHighRange;
274 else if ( shape ==
"CONE" ) {
280 else if( fIAxis == 2) {
283 fHighRange = 360.*
deg;
286 else if( fIAxis == 3) {
287 fHighRange = Rpar[0]*
cm;
288 fLowRange = -fHighRange;
291 else if ( shape ==
"CONS" ) {
297 else if( fIAxis == 2) {
299 fLowRange = Rpar[5]*
deg;
300 fHighRange = Rpar[6]*deg - fLowRange;
301 if ( Rpar[6]*deg <= fLowRange )fHighRange = fHighRange + 360.*
deg;
302 fHighRange = fHighRange + fLowRange;
305 else if( fIAxis == 3) {
306 fHighRange = Rpar[2]*
cm;
307 fLowRange = -fHighRange;
310 else if ( shape ==
"SPHE" ) {
312 fHighRange = Rpar[1]*
cm;
313 fLowRange = Rpar[0]*
cm;
316 else if( fIAxis == 2) {
317 fLowRange =
std::min(Rpar[2]*deg,Rpar[3]*deg);
318 fHighRange =
std::max(Rpar[2]*deg,Rpar[3]*deg);
321 else if( fIAxis == 3) {
322 fLowRange =
std::min(Rpar[4]*deg,Rpar[5]*deg);
323 fHighRange =
std::max(Rpar[4]*deg,Rpar[5]*deg);
327 else if ( shape ==
"PARA" ) {
328 fHighRange = Rpar[fIAxis-1]*
cm;
329 fLowRange = -fHighRange;
331 else if ( shape ==
"PGON" ) {
353 DzArray[i] = Rpar[i4]*
cm;
354 Rmin[i] = Rpar[i5]*
cm;
355 Rmax[i] = Rpar[i6]*
cm;
356 rangelo[0] =
std::min(rangelo[0], Rmin[i]);
357 rangehi[0] =
std::max(rangehi[0], Rmax[i]);
358 rangelo[2] =
std::min(rangelo[2], DzArray[i]);
359 rangehi[2] =
std::max(rangehi[2], DzArray[i]);
362 assert(Rmin[i]>=0 && Rmax[i]>=Rmin[i]);
364 rangehi[1] = pPhi1 + dPhi;
366 fHighRange = rangehi[fIAxis-1];
367 fLowRange = rangelo[fIAxis-1];
368 if (fIAxis == 1)fAxis =
kRho;
369 else if (fIAxis == 2)fAxis =
kPhi;
370 else if (fIAxis == 3)fAxis =
kZAxis;
377 else if ( shape ==
"PCON" ) {
399 DzArray[i] = Rpar[i4]*
cm;
400 Rmin[i] = Rpar[i5]*
cm;
401 Rmax[i] = Rpar[i6]*
cm;
402 rangelo[0] =
std::min(rangelo[0], Rmin[i]);
403 rangehi[0] =
std::max(rangehi[0], Rmax[i]);
404 rangelo[2] =
std::min(rangelo[2], DzArray[i]);
405 rangehi[2] =
std::max(rangehi[2], DzArray[i]);
408 assert(Rmin[i]>=0 && Rmax[i]>=Rmin[i]);
410 rangehi[1] = pPhi1 + dPhi;
412 fHighRange = rangehi[fIAxis-1];
413 fLowRange = rangelo[fIAxis-1];
414 if (fIAxis == 1)fAxis =
kRho;
415 else if (fIAxis == 2)fAxis =
kPhi;
416 else if (fIAxis == 3)fAxis =
kZAxis;
423 else if ( shape ==
"ELTU" || shape ==
"HYPE" || shape ==
"GTRA" ||
425 Exception(
"SetRangeAndAxis", shape);
428 Exception(
"SetRangeAndAxis",
"Unknown shape" + shape);
433 G4cout <<
"Shape " << shape <<
" SetRangeAndAxis: "
434 << fLowRange <<
" " << fHighRange <<
" " << fAxis <<
G4endl;
450 for (
G4int i=0; i<npar; ++i){ Rpar[i] = par[i];}
453 if ( shape ==
"BOX" ) {
454 Rpar[fIAxis-1] = (hi - lo)/2./
cm;
455 pos [fIAxis-1] = (hi + lo)/2.;
457 else if ( shape ==
"TRD1" ) {
458 if ( fIAxis == 1 || fIAxis == 2 ) {
459 Exception(
"CreateEnvelope",
"TRD1-x,y");
461 else if ( fIAxis == 3 ) {
464 tn = (Rpar[1] - Rpar[0])/(2.* Rpar[3]);
465 x1 = Rpar[0]; z1 = -Rpar[3];
466 Rpar[0] = x1 + tn * (lo/
cm - z1);
467 Rpar[1] = x1 + tn * (hi/
cm - z1);
468 Rpar[3] = (hi - lo)/2./
cm;
469 pos[2] = (hi + lo)/2.;
472 else if ( shape ==
"TRD2" ) {
473 if ( fIAxis == 1 || fIAxis == 2) {
474 Exception(
"CreateEnvelope",
"TRD2-x,y");
476 else if ( fIAxis == 3 ) {
480 tn1 = (Rpar[1] - Rpar[0])/(2.* Rpar[4]);
481 tn2 = (Rpar[3] - Rpar[2])/(2.* Rpar[4]);
482 x1 = Rpar[0]; y1 = Rpar[2]; z1 = -Rpar[3];
483 Rpar[0] = x1 + tn1 * (lo/
cm - z1);
484 Rpar[1] = x1 + tn1 * (hi/
cm - z1);
485 Rpar[2] = y1 + tn2 * (lo/
cm - z1);
486 Rpar[3] = y1 + tn2 * (hi/
cm - z1);
487 Rpar[4] = (hi - lo)/2./
cm;
488 pos[2] = (hi + lo)/2.;
491 else if ( shape ==
"TRAP" ) {
492 Exception(
"CreateEnvelope",
"TRAP-x,y,z");
494 else if ( shape ==
"TUBE" ) {
499 else if ( fIAxis == 2 ) {
505 else if ( fIAxis == 3 ) {
506 Rpar[2] = (hi - lo)/2./
cm;
507 pos [2] = (hi + lo)/2.;
510 else if ( shape ==
"TUBS" ) {
515 else if ( fIAxis == 2 ) {
519 else if ( fIAxis == 3 ) {
520 Rpar[2] = (hi - lo)/2./
cm;
521 pos [2] = (hi + lo)/2.;
524 else if ( shape ==
"CONE" ) {
526 Exception(
"CreateEnvelope",
"CONE-x,z");
528 else if ( fIAxis == 2 ) {
534 else if ( fIAxis == 3 ) {
536 tn1 = (Rpar[3] - Rpar[1])/(2.* Rpar[0]);
537 tn2 = (Rpar[4] - Rpar[2])/(2.* Rpar[0]);
538 rmin = Rpar[1]; rmax = Rpar[2]; z1 = -Rpar[0];
539 Rpar[1] = rmin + tn1 * (lo/
cm - z1);
540 Rpar[3] = rmin + tn1 * (hi/
cm - z1);
541 Rpar[2] = rmax + tn2 * (lo/
cm - z1);
542 Rpar[4] = rmax + tn2 * (hi/
cm - z1);
543 Rpar[0] = (hi - lo)/2./
cm;
544 pos[2] = (hi + lo)/2.;
547 else if ( shape ==
"CONS" ) {
549 Exception(
"CreateEnvelope",
"CONS-x");
551 else if ( fIAxis == 2 ) {
555 else if ( fIAxis == 3 ) {
557 tn1 = (Rpar[3] - Rpar[1])/(2.* Rpar[0]);
558 tn2 = (Rpar[4] - Rpar[2])/(2.* Rpar[0]);
559 rmin = Rpar[1]; rmax = Rpar[2]; z1 = -Rpar[0];
560 Rpar[1] = rmin + tn1 * (lo/
cm - z1);
561 Rpar[3] = rmin + tn1 * (hi/
cm - z1);
562 Rpar[2] = rmax + tn2 * (lo/
cm - z1);
563 Rpar[4] = rmax + tn2 * (hi/
cm - z1);
564 Rpar[0] = (hi - lo)/2./
cm;
565 pos[2] = (hi + lo)/2.;
568 else if ( shape ==
"SPHE" ) {
569 Exception(
"CreateEnvelope",
"SPHE-x,y,z");
571 else if ( shape ==
"PARA" ) {
572 Exception(
"CreateEnvelope",
"PARA-x,y,z");
574 else if ( shape ==
"PGON" ) {
581 Exception(
"CreateEnvelope",
"PGON-x,z");
584 else if ( shape ==
"PCON" ) {
591 Exception(
"CreateEnvelope",
"PCON-x,z");
595 Exception(
"CreateEnvelope",
"Unknown shape" + shape);
607 G3Pos* aG3Pos =
new G3Pos(motherName, 1, offset, 0, only);
620 for (
G4int i=0; i<npar; ++i){ Rpar[i] = par[i];}
629 if ( shape ==
"BOX" ) {
630 if ( fIAxis == 1 ) Rpar[0] = fWidth/2./
cm;
631 else if ( fIAxis == 2 ) Rpar[1] = fWidth/2./
cm;
632 else if ( fIAxis == 3 ) Rpar[2] = fWidth/2./
cm;
634 else if ( shape ==
"TRD1" ) {
635 if ( fIAxis == 1 || fIAxis == 2 ) {
636 Exception(
"CreateSolid",
"TRD1-x,y");
638 else if ( fIAxis == 3 ) {
639 Rpar[3] = fWidth/2./
cm;
642 else if ( shape ==
"TRD2" ) {
643 if ( fIAxis == 1 || fIAxis == 2 ) {
644 Exception(
"CreateSolid",
"TRD2-x,y");
646 else if ( fIAxis == 3 ) {
647 Rpar[4] = fWidth/2./
cm;
650 else if ( shape ==
"TRAP" ) {
651 if ( fIAxis == 1 || fIAxis == 2) {
652 Exception(
"CreateSolid",
"TRAP-x,y");
654 else if ( fIAxis == 3 ) {
655 Rpar[0] = fWidth/2./
cm;
658 else if ( shape ==
"TUBE" ) {
660 Rpar[1] = Rpar[0] + fWidth/
cm;
661 fOffset = Rpar[0]*
cm;
663 else if ( fIAxis == 2 ) {
665 Rpar[4] = fWidth/
deg;
669 else if ( fIAxis == 3 ) {
670 Rpar[2] = fWidth/2./
cm;
673 else if ( shape ==
"TUBS" ) {
675 Rpar[1] = Rpar[0] + fWidth/
cm;
676 fOffset = Rpar[0]*
cm;
678 else if ( fIAxis == 2 ) {
679 fOffset = Rpar[3]*
deg;
681 Rpar[4] = fWidth/
deg;
683 else if ( fIAxis == 3 ) {
684 Rpar[2] = fWidth/2./
cm;
687 else if ( shape ==
"CONE" ) {
689 Exception(
"CreateSolid",
"CONE-x");
691 else if ( fIAxis == 2 ) {
693 Rpar[6] = fWidth/
deg;
697 else if ( fIAxis == 3 ) {
698 Rpar[0] = fWidth/2./
cm;
701 else if ( shape ==
"CONS" ) {
703 Exception(
"CreateSolid",
"CONS-x");
705 else if ( fIAxis == 2 ) {
706 fOffset = Rpar[5]*
deg;
708 Rpar[6] = fWidth/
deg;
710 else if ( fIAxis == 3 ) {
711 Rpar[0] = fWidth/2./
cm;
714 else if (shape ==
"PARA") {
716 Rpar[0] = fWidth/2./
cm;
718 else if ( Rpar[4] == 0. && Rpar[5] == 0. ) {
721 Rpar[1] = fWidth/2./
cm;
723 else if ( fIAxis == 3) {
724 Rpar[2] = fWidth/2./
cm;
728 Exception(
"CreateSolid", shape);
730 else if (shape ==
"SPHE") {
731 Exception(
"CreateSolid", shape);
733 else if ( shape ==
"PGON" ) {
735 fOffset = Rpar[0]*
deg;
737 Rpar[1] = fWidth/
deg;
741 Exception(
"CreateSolid", shape);
743 else if ( shape ==
"PCON" ) {
745 fOffset = Rpar[0]*
deg;
747 Rpar[1] = fWidth/
deg;
750 Exception(
"CreateSolid", shape);
754 Exception(
"CreateSolid",
"Unknown shape" + shape);
766 +
" has negative parameters.";
767 G4Exception(
"G3Division::CreateSolid()",
"G3toG40006",
797 fWidth = (fHighRange - fLowRange)/fNofDivisions;
798 CreateSolid(shape, Rpar, npar);
813 if (fAxis ==
kPhi) c0 = c0*
deg;
818 if( std::abs(c0 - fLowRange) > Rmin) {
819 envVTE = CreateEnvelope(shape, fHighRange, c0, Rpar, npar);
825 fWidth = (fHighRange - c0)/fNofDivisions;
826 CreateSolid(shape, Rpar, npar);
842 G4int ndvmx = fNofDivisions;
845 if (fAxis ==
kPhi) step = step*
deg;
848 G4int ndiv =
G4int((fHighRange - fLowRange + Rmin)/step);
850 if (ndvmx > 255) ndvmx = 255;
851 if (ndiv > ndvmx && ndvmx > 0 ) ndiv = ndvmx;
855 G4double delta = std::abs((fHighRange - fLowRange) - ndiv*step);
858 = CreateEnvelope(shape, fHighRange-delta/2., fLowRange+delta/2.,
866 fNofDivisions = ndiv;
867 CreateSolid(shape, Rpar, npar);
883 G4int ndvmx = fNofDivisions;
896 G4int ndiv =
G4int((fHighRange - c0 + Rmin)/step);
898 if (ndvmx > 255) ndvmx = 255;
899 if (ndiv > ndvmx && ndvmx > 0 ) ndiv = ndvmx;
903 G4double delta = std::abs((fHighRange - c0) - ndiv*step);
904 if (std::abs(c0 - fLowRange) > Rmin) {
906 = CreateEnvelope(shape, fHighRange-delta/2., c0+delta/2., Rpar, npar);
913 fNofDivisions = ndiv;
914 CreateSolid(shape, Rpar, npar);
G3G4DLL_API G4double Rpar[1000]
static const G4double kInfinity
CLHEP::Hep3Vector G4ThreeVector
G3VolTableEntry * GetMasterClone()
G4LogicalVolume * GetLV()
G4VSolid * GetSolid() const
G4PhysicalVolumesPair Replicate(const G4String &name, G4LogicalVolume *LV, G4LogicalVolume *motherLV, EAxis axis, G4int nofReplicas, G4double width, G4double offset=0)
static G4ReflectionFactory * Instance()
G4GLOB_DLL std::ostream G4cout
G4PhysicalVolumesPair Place(const G4Transform3D &transform3D, const G4String &name, G4LogicalVolume *LV, G4LogicalVolume *motherLV, G4bool isMany, G4int copyNo, G4bool surfCheck=false)
void SetNRpar(G4int npar, G4double *Rpar)
static constexpr double cm
G3Division(G3DivType type, G3VolTableEntry *vte, G3VolTableEntry *mvte, G4int nofDivision, G4int iaxis, G4int nmed, G4double c0, G4double step)
void SetHasNegPars(G4bool hasNegPars)
void SetSolid(G4VSolid *solid)
G3VolTableEntry * G4CreateVTE(G4String vname, G4String shape, G4int nmed, G4double Rpar[], G4int npar)
G4VSolid * G3toG4MakeSolid(const G4String &vname, const G4String &shape, const G4double *Rpar, const G4int npar, G4bool &NegVolPars, G4bool &Deferred, G4bool *OKAxis)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
void AddG3Pos(G3Pos *aG3Pos)
void AddMother(G3VolTableEntry *aDaughter)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
void ReplaceMother(G3VolTableEntry *vteOld, G3VolTableEntry *vteNew)
void ReplaceDaughter(G3VolTableEntry *vteOld, G3VolTableEntry *vteNew)
const G4String & GetName() const
static constexpr double deg
static const G4double pos
void AddDaughter(G3VolTableEntry *aDaughter)