ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ParameterisationPolycone.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4ParameterisationPolycone.cc
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 // G4ParameterisationPolycone[Rho/Phi/Z] implementation
27 //
28 // 26.05.03 - P.Arce, Initial version
29 // 08.04.04 - I.Hrivnacova, Implemented reflection
30 //---------------------------------------------------------------------
31 
33 
34 #include <iomanip>
35 #include "G4ThreeVector.hh"
36 #include "G4RotationMatrix.hh"
37 #include "G4VPhysicalVolume.hh"
38 #include "G4LogicalVolume.hh"
39 #include "G4ReflectedSolid.hh"
40 
41 //-----------------------------------------------------------------------
44  G4double offset, G4VSolid* msolid,
45  DivisionType divType )
46  : G4VDivisionParameterisation( axis, nDiv, width, offset, divType, msolid )
47 {
48 #ifdef G4MULTITHREADED
49  std::ostringstream message;
50  message << "Divisions for G4Polycone currently NOT supported in MT-mode."
51  << G4endl
52  << "Sorry! Solid: " << msolid->GetName();
53  G4Exception("G4VParameterisationPolycone::G4VParameterisationPolycone()",
54  "GeomDiv0001", FatalException, message);
55 #endif
56  G4Polycone* msol = (G4Polycone*)(msolid);
57  if (msolid->GetEntityType() == "G4ReflectedSolid")
58  {
59  // Get constituent solid
60  //
61  G4VSolid* mConstituentSolid
62  = ((G4ReflectedSolid*)msolid)->GetConstituentMovedSolid();
63  msol = (G4Polycone*)(mConstituentSolid);
64 
65  // Get parameters
66  //
67  G4int nofZplanes = msol->GetOriginalParameters()->Num_z_planes;
68  G4double* zValues = msol->GetOriginalParameters()->Z_values;
69  G4double* rminValues = msol->GetOriginalParameters()->Rmin;
70  G4double* rmaxValues = msol->GetOriginalParameters()->Rmax;
71 
72  // Invert z values
73  //
74  G4double* zValuesRefl = new G4double[nofZplanes];
75  for (G4int i=0; i<nofZplanes; ++i) { zValuesRefl[i] = - zValues[i]; }
76 
77  G4Polycone* newSolid
78  = new G4Polycone(msol->GetName(),
79  msol->GetStartPhi(),
80  msol->GetEndPhi() - msol->GetStartPhi(),
81  nofZplanes, zValuesRefl, rminValues, rmaxValues);
82 
83  delete [] zValuesRefl;
84 
85  msol = newSolid;
86  fmotherSolid = newSolid;
87  fReflectedSolid = true;
88  fDeleteSolid = true;
89  }
90 }
91 
92 //---------------------------------------------------------------------
94 {
95 }
96 
97 //---------------------------------------------------------------------
100  G4double width, G4double offset,
101  G4VSolid* msolid, DivisionType divType )
102  : G4VParameterisationPolycone( axis, nDiv, width, offset, msolid, divType )
103 {
105  SetType( "DivisionPolyconeRho" );
106 
107  G4Polycone* msol = (G4Polycone*)(fmotherSolid);
108  G4PolyconeHistorical* origparamMother = msol->GetOriginalParameters();
109 
110  if( divType == DivWIDTH )
111  {
112  fnDiv = CalculateNDiv( origparamMother->Rmax[0]
113  - origparamMother->Rmin[0], width, offset );
114  }
115  else if( divType == DivNDIV )
116  {
117  fwidth = CalculateWidth( origparamMother->Rmax[0]
118  - origparamMother->Rmin[0], nDiv, offset );
119  }
120 
121 #ifdef G4DIVDEBUG
122  if( verbose >= -1 )
123  {
124  G4cout << " G4ParameterisationPolyconeRho - # divisions " << fnDiv
125  << " = " << nDiv << G4endl
126  << " Offset " << foffset << " = " << offset << G4endl
127  << " Width " << fwidth << " = " << width << G4endl;
128  }
129 #endif
130 }
131 
132 //---------------------------------------------------------------------
134 {
135 }
136 
137 //---------------------------------------------------------------------
139 {
141 
142  G4Polycone* msol = (G4Polycone*)(fmotherSolid);
143 
145  {
146  std::ostringstream message;
147  message << "In solid " << msol->GetName() << G4endl
148  << "Division along R will be done with a width "
149  << "different for each solid section." << G4endl
150  << "WIDTH will not be used !";
151  G4Exception("G4VParameterisationPolycone::CheckParametersValidity()",
152  "GeomDiv1001", JustWarning, message);
153  }
154  if( foffset != 0. )
155  {
156  std::ostringstream message;
157  message << "In solid " << msol->GetName() << G4endl
158  << "Division along R will be done with a width "
159  << "different for each solid section." << G4endl
160  << "OFFSET will not be used !";
161  G4Exception("G4VParameterisationPolycone::CheckParametersValidity()",
162  "GeomDiv1001", JustWarning, message);
163  }
164 }
165 
166 //------------------------------------------------------------------------
168 {
169  G4Polycone* msol = (G4Polycone*)(fmotherSolid);
170  G4PolyconeHistorical* original_pars = msol->GetOriginalParameters();
171  return original_pars->Rmax[0] - original_pars->Rmin[0];
172 }
173 
174 
175 //---------------------------------------------------------------------
176 void
179 {
180  //----- translation
181  G4ThreeVector origin(0.,0.,0.);
182  //----- set translation
183  physVol->SetTranslation( origin );
184 
185  //----- calculate rotation matrix: unit
186 
187 #ifdef G4DIVDEBUG
188  if( verbose >= 2 )
189  {
190  G4cout << " G4ParameterisationPolyconeRho " << G4endl
191  << " foffset: " << foffset
192  << " - fwidth: " << fwidth << G4endl;
193  }
194 #endif
195 
196  ChangeRotMatrix( physVol );
197 
198 #ifdef G4DIVDEBUG
199  if( verbose >= 2 )
200  {
201  G4cout << std::setprecision(8) << " G4ParameterisationPolyconeRho "
202  << G4endl
203  << " Position: " << origin/mm
204  << " - Width: " << fwidth/deg
205  << " - Axis: " << faxis << G4endl;
206  }
207 #endif
208 }
209 
210 //---------------------------------------------------------------------
211 void
213 ComputeDimensions( G4Polycone& pcone, const G4int copyNo,
214  const G4VPhysicalVolume* ) const
215 {
216  G4Polycone* msol = (G4Polycone*)(fmotherSolid);
217 
218  G4PolyconeHistorical* origparamMother = msol->GetOriginalParameters();
219  G4PolyconeHistorical origparam( *origparamMother );
220  G4int nZplanes = origparamMother->Num_z_planes;
221 
222  G4double width = 0.;
223  for( G4int ii = 0; ii < nZplanes; ++ii )
224  {
225  width = CalculateWidth( origparamMother->Rmax[ii]
226  - origparamMother->Rmin[ii], fnDiv, foffset );
227  origparam.Rmin[ii] = origparamMother->Rmin[ii]+foffset+width*copyNo;
228  origparam.Rmax[ii] = origparamMother->Rmin[ii]+foffset+width*(copyNo+1);
229  }
230 
231  pcone.SetOriginalParameters(&origparam); // copy values & transfer pointers
232  pcone.Reset(); // reset to new solid parameters
233 
234 #ifdef G4DIVDEBUG
235  if( verbose >= -2 )
236  {
237  G4cout << "G4ParameterisationPolyconeRho::ComputeDimensions()" << G4endl
238  << "-- Parametrised pcone copy-number: " << copyNo << G4endl;
239  pcone.DumpInfo();
240  }
241 #endif
242 }
243 
244 //---------------------------------------------------------------------
247  G4double width, G4double offset,
248  G4VSolid* msolid, DivisionType divType )
249  : G4VParameterisationPolycone( axis, nDiv, width, offset, msolid, divType )
250 {
252  SetType( "DivisionPolyconePhi" );
253 
254  G4Polycone* msol = (G4Polycone*)(fmotherSolid);
255  G4double deltaPhi = msol->GetEndPhi() - msol->GetStartPhi();
256 
257  if( divType == DivWIDTH )
258  {
259  fnDiv = CalculateNDiv( deltaPhi, width, offset );
260  }
261  else if( divType == DivNDIV )
262  {
263  fwidth = CalculateWidth( deltaPhi, nDiv, offset );
264  }
265 
266 #ifdef G4DIVDEBUG
267  if( verbose >= 1 )
268  {
269  G4cout << " G4ParameterisationPolyconePhi - # divisions " << fnDiv
270  << " = " << nDiv << G4endl
271  << " Offset " << foffset/deg << " = " << offset/deg << G4endl
272  << " Width " << fwidth/deg << " = " << width/deg << G4endl;
273  }
274 #endif
275 }
276 
277 //---------------------------------------------------------------------
279 {
280 }
281 
282 //------------------------------------------------------------------------
284 {
285  G4Polycone* msol = (G4Polycone*)(fmotherSolid);
286  return msol->GetEndPhi() - msol->GetStartPhi();
287 }
288 
289 //---------------------------------------------------------------------
290 void
292 ComputeTransformation( const G4int copyNo, G4VPhysicalVolume* physVol ) const
293 {
294  //----- translation
295  G4ThreeVector origin(0.,0.,0.);
296  //----- set translation
297  physVol->SetTranslation( origin );
298 
299  //----- calculate rotation matrix (so that all volumes point to the centre)
300  G4double posi = foffset + copyNo*fwidth;
301 
302 #ifdef G4DIVDEBUG
303  if( verbose >= 2 )
304  {
305  G4cout << " G4ParameterisationPolyconePhi - position: " << posi/deg
306  << G4endl
307  << " copyNo: " << copyNo << " - foffset: " << foffset/deg
308  << " - fwidth: " << fwidth/deg << G4endl;
309  }
310 #endif
311 
312  ChangeRotMatrix( physVol, -posi );
313 
314 #ifdef G4DIVDEBUG
315  if( verbose >= 2 )
316  {
317  G4cout << std::setprecision(8) << " G4ParameterisationPolyconePhi "
318  << copyNo << G4endl
319  << " Position: " << origin << " - Width: " << fwidth
320  << " - Axis: " << faxis << G4endl;
321  }
322 #endif
323 }
324 
325 //---------------------------------------------------------------------
326 void
329  const G4VPhysicalVolume* ) const
330 {
331  G4Polycone* msol = (G4Polycone*)(fmotherSolid);
332 
333  G4PolyconeHistorical* origparamMother = msol->GetOriginalParameters();
334  G4PolyconeHistorical origparam( *origparamMother );
335  origparam.Start_angle = origparamMother->Start_angle;
336  origparam.Opening_angle = fwidth;
337 
338  pcone.SetOriginalParameters(&origparam); // copy values & transfer pointers
339  pcone.Reset(); // reset to new solid parameters
340 
341 #ifdef G4DIVDEBUG
342  if( verbose >= 2 )
343  {
344  G4cout << "G4ParameterisationPolyconePhi::ComputeDimensions():" << G4endl;
345  pcone.DumpInfo();
346  }
347 #endif
348 }
349 
350 //---------------------------------------------------------------------
353  G4double width, G4double offset,
354  G4VSolid* msolid, DivisionType divType)
355  : G4VParameterisationPolycone( axis, nDiv, width, offset, msolid, divType ),
356  fOrigParamMother(((G4Polycone*)fmotherSolid)->GetOriginalParameters())
357 {
358 
360  SetType( "DivisionPolyconeZ" );
361 
362  if( divType == DivWIDTH )
363  {
364  fnDiv =
366  - fOrigParamMother->Z_values[0] , width, offset );
367  }
368  else if( divType == DivNDIV )
369  {
370  fwidth =
372  - fOrigParamMother->Z_values[0] , nDiv, offset );
373  }
374 
375 #ifdef G4DIVDEBUG
376  if( verbose >= 1 )
377  {
378  G4cout << " G4ParameterisationPolyconeZ - # divisions " << fnDiv << " = "
379  << nDiv << G4endl
380  << " Offset " << foffset << " = " << offset << G4endl
381  << " Width " << fwidth << " = " << width << G4endl;
382  }
383 #endif
384 }
385 
386 //---------------------------------------------------------------------
388 {
389 }
390 
391 //------------------------------------------------------------------------
394  G4double z2, G4double r2) const
395 {
396  // Linear parameterisation:
397  // r = az + b
398  // a = (r1 - r2)/(z1-z2)
399  // b = r1 - a*z1
400 
401  return (r1-r2)/(z1-z2)*z + ( r1 - (r1-r2)/(z1-z2)*z1 ) ;
402 }
403 
404 //------------------------------------------------------------------------
406 {
407 // Get Rmin in the given z position for the given polycone segment
408 
409  return GetR(z,
410  fOrigParamMother->Z_values[nseg],
411  fOrigParamMother->Rmin[nseg],
412  fOrigParamMother->Z_values[nseg+1],
413  fOrigParamMother->Rmin[nseg+1]);
414 }
415 
416 //------------------------------------------------------------------------
418 {
419 // Get Rmax in the given z position for the given polycone segment
420 
421  return GetR(z,
422  fOrigParamMother->Z_values[nseg],
423  fOrigParamMother->Rmax[nseg],
424  fOrigParamMother->Z_values[nseg+1],
425  fOrigParamMother->Rmax[nseg+1]);
426 }
427 
428 //------------------------------------------------------------------------
430 {
433 }
434 
435 //---------------------------------------------------------------------
437 {
439 
440  // Division will be following the mother polycone segments
441  //
442  if( fDivisionType == DivNDIV )
443  {
445  {
446  std::ostringstream error;
447  error << "Configuration not supported." << G4endl
448  << "Division along Z will be done by splitting in the defined"
449  << G4endl
450  << "Z planes, i.e, the number of division would be: "
452  << ", instead of: " << fnDiv << " !";
453  G4Exception("G4ParameterisationPolyconeZ::CheckParametersValidity()",
454  "GeomDiv0001", FatalException, error);
455  }
456  }
457 
458  // Division will be done within one polycone segment
459  // with applying given width and offset
460  //
462  {
463  // Check if divided region does not span over more
464  // than one z segment
465 
466  G4int isegstart = -1; // number of the segment containing start position
467  G4int isegend = -1; // number of the segment containing end position
468 
469  if ( !fReflectedSolid )
470  {
471  // The start/end position of the divided region
472  //
473  G4double zstart
475  G4double zend
477 
478  G4int counter = 0;
479  while ( isegend < 0 && counter < fOrigParamMother->Num_z_planes-1 )
480  {
481  // first segment
482  if ( zstart >= fOrigParamMother->Z_values[counter] &&
483  zstart < fOrigParamMother->Z_values[counter+1] )
484  {
485  isegstart = counter;
486  }
487  // last segment
488  if ( zend > fOrigParamMother->Z_values[counter] &&
489  zend <= fOrigParamMother->Z_values[counter+1] )
490  {
491  isegend = counter;
492  }
493  ++counter;
494  } // Loop checking, 06.08.2015, G.Cosmo
495  }
496  else
497  {
498  // The start/end position of the divided region
499  //
500  G4double zstart
502  G4double zend
504 
505  G4int counter = 0;
506  while ( isegend < 0 && counter < fOrigParamMother->Num_z_planes-1 )
507  {
508  // first segment
509  if ( zstart <= fOrigParamMother->Z_values[counter] &&
510  zstart > fOrigParamMother->Z_values[counter+1] )
511  {
512  isegstart = counter;
513  }
514  // last segment
515  if ( zend < fOrigParamMother->Z_values[counter] &&
516  zend >= fOrigParamMother->Z_values[counter+1] )
517  {
518  isegend = counter;
519  }
520  ++counter;
521  } // Loop checking, 06.08.2015, G.Cosmo
522  }
523 
524 
525  if ( isegstart != isegend )
526  {
527  std::ostringstream message;
528  message << "Condiguration not supported." << G4endl
529  << "Division with user defined width." << G4endl
530  << "Solid " << fmotherSolid->GetName() << G4endl
531  << "Divided region is not between two z planes.";
532  G4Exception("G4ParameterisationPolyconeZ::CheckParametersValidity()",
533  "GeomDiv0001", FatalException, message);
534  }
535 
536  fNSegment = isegstart;
537  }
538 }
539 
540 //---------------------------------------------------------------------
541 void
543 ComputeTransformation( const G4int copyNo, G4VPhysicalVolume* physVol) const
544 {
545  if ( fDivisionType == DivNDIV )
546  {
547  // The position of the centre of copyNo-th mother polycone segment
548  //
549  G4double posi = ( fOrigParamMother->Z_values[copyNo]
550  + fOrigParamMother->Z_values[copyNo+1])/2;
551  physVol->SetTranslation( G4ThreeVector(0, 0, posi) );
552  }
553 
555  {
556  // The position of the centre of copyNo-th division
557  //
559 
560  if ( !fReflectedSolid )
561  posi += foffset + (2*copyNo + 1) * fwidth/2.;
562  else
563  posi -= foffset + (2*copyNo + 1) * fwidth/2.;
564 
565  physVol->SetTranslation( G4ThreeVector(0, 0, posi) );
566  }
567 
568  //----- calculate rotation matrix: unit
569 
570 #ifdef G4DIVDEBUG
571  if( verbose >= 2 )
572  {
573  G4cout << " G4ParameterisationPolyconeZ - position: " << posi << G4endl
574  << " copyNo: " << copyNo << " - foffset: " << foffset/deg
575  << " - fwidth: " << fwidth/deg << G4endl;
576  }
577 #endif
578 
579  ChangeRotMatrix( physVol );
580 
581 #ifdef G4DIVDEBUG
582  if( verbose >= 2 )
583  {
584  G4cout << std::setprecision(8) << " G4ParameterisationPolyconeZ "
585  << copyNo << G4endl
586  << " Position: " << origin << " - Width: " << fwidth
587  << " - Axis: " << faxis << G4endl;
588  }
589 #endif
590 }
591 
592 //---------------------------------------------------------------------
593 void
595 ComputeDimensions( G4Polycone& pcone, const G4int copyNo,
596  const G4VPhysicalVolume* ) const
597 {
598 
599  // Define division solid
600  //
601  G4PolyconeHistorical origparam;
602  G4int nz = 2;
603  origparam.Num_z_planes = nz;
606 
607  // Define division solid z sections
608  //
609  origparam.Z_values = new G4double[nz];
610  origparam.Rmin = new G4double[nz];
611  origparam.Rmax = new G4double[nz];
612 
613  if ( fDivisionType == DivNDIV )
614  {
615  // The position of the centre of copyNo-th mother polycone segment
616  G4double posi = (fOrigParamMother->Z_values[copyNo]
617  + fOrigParamMother->Z_values[copyNo+1])/2;
618 
619  origparam.Z_values[0] = fOrigParamMother->Z_values[copyNo] - posi;
620  origparam.Z_values[1] = fOrigParamMother->Z_values[copyNo+1] - posi;
621  origparam.Rmin[0] = fOrigParamMother->Rmin[copyNo];
622  origparam.Rmin[1] = fOrigParamMother->Rmin[copyNo+1];
623  origparam.Rmax[0] = fOrigParamMother->Rmax[copyNo];
624  origparam.Rmax[1] = fOrigParamMother->Rmax[copyNo+1];
625  }
626 
628  {
629  if ( !fReflectedSolid )
630  {
631  origparam.Z_values[0] = - fwidth/2.;
632  origparam.Z_values[1] = fwidth/2.;
633 
634  // The position of the centre of copyNo-th division
635  //
637  + foffset + (2*copyNo + 1) * fwidth/2.;
638 
639  // The first and last z sides z values
640  //
641  G4double zstart = posi - fwidth/2.;
642  G4double zend = posi + fwidth/2.;
643  origparam.Rmin[0] = GetRmin(zstart, fNSegment);
644  origparam.Rmax[0] = GetRmax(zstart, fNSegment);
645  origparam.Rmin[1] = GetRmin(zend, fNSegment);
646  origparam.Rmax[1] = GetRmax(zend, fNSegment);
647  }
648  else
649  {
650  origparam.Z_values[0] = fwidth/2.;
651  origparam.Z_values[1] = - fwidth/2.;
652 
653  // The position of the centre of copyNo-th division
654  //
656  - ( foffset + (2*copyNo + 1) * fwidth/2.);
657 
658  // The first and last z sides z values
659  //
660  G4double zstart = posi + fwidth/2.;
661  G4double zend = posi - fwidth/2.;
662  origparam.Rmin[0] = GetRmin(zstart, fNSegment);
663  origparam.Rmax[0] = GetRmax(zstart, fNSegment);
664  origparam.Rmin[1] = GetRmin(zend, fNSegment);
665  origparam.Rmax[1] = GetRmax(zend, fNSegment);
666  }
667 
668  // It can happen due to rounding errors
669  //
670  if ( origparam.Rmin[0] < 0.0 ) origparam.Rmin[0] = 0.0;
671  if ( origparam.Rmin[nz-1] < 0.0 ) origparam.Rmin[1] = 0.0;
672  }
673 
674  pcone.SetOriginalParameters(&origparam); // copy values & transfer pointers
675  pcone.Reset(); // reset to new solid parameters
676 
677 #ifdef G4DIVDEBUG
678  if( verbose >= 2 )
679  {
680  G4cout << "G4ParameterisationPolyconeZ::ComputeDimensions()" << G4endl
681  << "-- Parametrised pcone copy-number: " << copyNo << G4endl;
682  pcone.DumpInfo();
683  }
684 #endif
685 }