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
00032
00033
00034
00035
00036 #include "G4ParameterisationTrd.hh"
00037
00038 #include <iomanip>
00039 #include "G4ThreeVector.hh"
00040 #include "G4RotationMatrix.hh"
00041 #include "G4VPhysicalVolume.hh"
00042 #include "G4LogicalVolume.hh"
00043 #include "G4ReflectedSolid.hh"
00044 #include "G4Trd.hh"
00045 #include "G4Trap.hh"
00046
00047
00048 G4VParameterisationTrd::
00049 G4VParameterisationTrd( EAxis axis, G4int nDiv, G4double width,
00050 G4double offset, G4VSolid* msolid,
00051 DivisionType divType )
00052 : G4VDivisionParameterisation( axis, nDiv, width, offset, divType, msolid ),
00053 bDivInTrap(false)
00054 {
00055 G4Trd* msol = (G4Trd*)(msolid);
00056 if (msolid->GetEntityType() == "G4ReflectedSolid")
00057 {
00058
00059 G4VSolid* mConstituentSolid
00060 = ((G4ReflectedSolid*)msolid)->GetConstituentMovedSolid();
00061 msol = (G4Trd*)(mConstituentSolid);
00062
00063
00064 G4Trd* newSolid
00065 = new G4Trd(msol->GetName(),
00066 msol->GetXHalfLength2(), msol->GetXHalfLength1(),
00067 msol->GetYHalfLength2(), msol->GetYHalfLength1(),
00068 msol->GetZHalfLength());
00069 msol = newSolid;
00070 fmotherSolid = newSolid;
00071 fReflectedSolid = true;
00072 fDeleteSolid = true;
00073 }
00074 }
00075
00076
00077 G4VParameterisationTrd::~G4VParameterisationTrd()
00078 {
00079 }
00080
00081
00082 G4ParameterisationTrdX::
00083 G4ParameterisationTrdX( EAxis axis, G4int nDiv,
00084 G4double width, G4double offset,
00085 G4VSolid* msolid, DivisionType divType )
00086 : G4VParameterisationTrd( axis, nDiv, width, offset, msolid, divType )
00087 {
00088 CheckParametersValidity();
00089 SetType( "DivisionTrdX" );
00090
00091 G4Trd* msol = (G4Trd*)(fmotherSolid);
00092 if( divType == DivWIDTH )
00093 {
00094 fnDiv = CalculateNDiv( msol->GetXHalfLength1()+msol->GetXHalfLength2(),
00095 width, offset );
00096 }
00097 else if( divType == DivNDIV )
00098 {
00099 fwidth = CalculateWidth( msol->GetXHalfLength1()+msol->GetXHalfLength2(),
00100 nDiv, offset );
00101 }
00102
00103 #ifdef G4DIVDEBUG
00104 if( verbose >= 1 )
00105 {
00106 G4cout << " G4ParameterisationTrdX - ## divisions " << fnDiv << " = "
00107 << nDiv << G4endl
00108 << " Offset " << foffset << " = " << offset << G4endl
00109 << " Width " << fwidth << " = " << width << G4endl;
00110 }
00111 #endif
00112
00113 G4double mpDx1 = msol->GetXHalfLength1();
00114 G4double mpDx2 = msol->GetXHalfLength2();
00115 if( std::fabs(mpDx1 - mpDx2) > kCarTolerance )
00116 {
00117 bDivInTrap = true;
00118 }
00119 }
00120
00121
00122 G4ParameterisationTrdX::~G4ParameterisationTrdX()
00123 {
00124 }
00125
00126
00127 G4double G4ParameterisationTrdX::GetMaxParameter() const
00128 {
00129 G4Trd* msol = (G4Trd*)(fmotherSolid);
00130 return (msol->GetXHalfLength1()+msol->GetXHalfLength2());
00131 }
00132
00133
00134 void
00135 G4ParameterisationTrdX::
00136 ComputeTransformation( const G4int copyNo,
00137 G4VPhysicalVolume *physVol ) const
00138 {
00139 G4Trd* msol = (G4Trd*)(fmotherSolid );
00140 G4double mdx = ( msol->GetXHalfLength1() + msol->GetXHalfLength2() ) / 2.;
00141
00142
00143 G4ThreeVector origin(0.,0.,0.);
00144 G4double posi;
00145 if( !bDivInTrap )
00146 {
00147 posi = -mdx + foffset + (copyNo+0.5)*fwidth;
00148 }
00149 else
00150 {
00151 G4double aveHL = (msol->GetXHalfLength1()+msol->GetXHalfLength2())/2.;
00152 posi = - aveHL + foffset + (copyNo+0.5)*aveHL/fnDiv*2;
00153 }
00154 if( faxis == kXAxis )
00155 {
00156 origin.setX( posi );
00157 }
00158 else
00159 {
00160 std::ostringstream message;
00161 message << "Only axes along X are allowed ! Axis: " << faxis;
00162 G4Exception("G4ParameterisationTrdX::ComputeTransformation()",
00163 "GeomDiv0002", FatalException, message);
00164 }
00165
00166 #ifdef G4DIVDEBUG
00167 if( verbose >= 2 )
00168 {
00169 G4cout << std::setprecision(8)
00170 << " G4ParameterisationTrdX::ComputeTransformation() "
00171 << copyNo << G4endl
00172 << " Position: " << origin << " - Axis: " << faxis << G4endl;
00173 }
00174 #endif
00175
00176
00177 physVol->SetTranslation( origin );
00178 }
00179
00180
00181 void
00182 G4ParameterisationTrdX::
00183 ComputeDimensions( G4Trd& trd, const G4int, const G4VPhysicalVolume* ) const
00184 {
00185 G4Trd* msol = (G4Trd*)(fmotherSolid);
00186
00187 G4double pDy1 = msol->GetYHalfLength1();
00188 G4double pDy2 = msol->GetYHalfLength2();
00189 G4double pDz = msol->GetZHalfLength();
00190 G4double pDx = fwidth/2. - fhgap;
00191
00192 trd.SetAllParameters ( pDx, pDx, pDy1, pDy2, pDz );
00193
00194 #ifdef G4DIVDEBUG
00195 if( verbose >= 2 )
00196 {
00197 G4cout << " G4ParameterisationTrdX::ComputeDimensions():"
00198 << copyNo << G4endl;
00199 trd.DumpInfo();
00200 }
00201 #endif
00202 }
00203
00204 G4VSolid* G4ParameterisationTrdX::
00205 ComputeSolid(const G4int i, G4VPhysicalVolume * pv)
00206 {
00207 if( bDivInTrap )
00208 {
00209 return G4VDivisionParameterisation::ComputeSolid(i, pv);
00210 }
00211 else
00212 {
00213 return fmotherSolid;
00214 }
00215 }
00216
00217
00218
00219 void
00220 G4ParameterisationTrdX::ComputeDimensions( G4Trap& trap, const G4int copyNo,
00221 const G4VPhysicalVolume* ) const
00222 {
00223 G4Trd* msol = (G4Trd*)(fmotherSolid);
00224 G4double pDy1 = msol->GetYHalfLength1();
00225 G4double pDy2 = msol->GetYHalfLength2();
00226 G4double pDz = msol->GetZHalfLength();
00227 G4double pDx1 = msol->GetXHalfLength1()/fnDiv;
00228 G4double pDx2 = msol->GetXHalfLength2()/fnDiv;
00229
00230 G4double cxy1 = -msol->GetXHalfLength1() + foffset
00231 + (copyNo+0.5)*pDx1*2;
00232 G4double cxy2 = -msol->GetXHalfLength2() + foffset
00233 + (copyNo+0.5)*pDx2*2;
00234 G4double alp = std::atan( (cxy2-cxy1)/pDz );
00235
00236 trap.SetAllParameters ( pDz,
00237 0.,
00238 0.,
00239 pDy1,
00240 pDx1,
00241 pDx2,
00242 alp,
00243 pDy2,
00244 pDx1 - fhgap,
00245 pDx2 - fhgap * pDx2/pDx1,
00246 alp);
00247
00248 #ifdef G4DIVDEBUG
00249 if( verbose >= 2 )
00250 {
00251 G4cout << " G4ParameterisationTrdX::ComputeDimensions():"
00252 << copyNo << G4endl;
00253 trap.DumpInfo();
00254 }
00255 #endif
00256 }
00257
00258
00259 void G4ParameterisationTrdX::CheckParametersValidity()
00260 {
00261 G4VDivisionParameterisation::CheckParametersValidity();
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 }
00282
00283
00284 void G4ParameterisationTrdX::
00285 ComputeTrapParams()
00286 {
00287 }
00288
00289
00290 G4ParameterisationTrdY::
00291 G4ParameterisationTrdY( EAxis axis, G4int nDiv,
00292 G4double width, G4double offset,
00293 G4VSolid* msolid, DivisionType divType)
00294 : G4VParameterisationTrd( axis, nDiv, width, offset, msolid, divType )
00295 {
00296 CheckParametersValidity();
00297 SetType( "DivisionTrdY" );
00298
00299 G4Trd* msol = (G4Trd*)(fmotherSolid);
00300 if( divType == DivWIDTH )
00301 {
00302 fnDiv = CalculateNDiv( 2*msol->GetYHalfLength1(),
00303 width, offset );
00304 }
00305 else if( divType == DivNDIV )
00306 {
00307 fwidth = CalculateWidth( 2*msol->GetYHalfLength1(),
00308 nDiv, offset );
00309 }
00310
00311 #ifdef G4DIVDEBUG
00312 if( verbose >= 1 )
00313 {
00314 G4cout << " G4ParameterisationTrdY no divisions " << fnDiv
00315 << " = " << nDiv << G4endl
00316 << " Offset " << foffset << " = " << offset << G4endl
00317 << " width " << fwidth << " = " << width << G4endl;
00318 }
00319 #endif
00320 }
00321
00322
00323 G4ParameterisationTrdY::~G4ParameterisationTrdY()
00324 {
00325 }
00326
00327
00328 G4double G4ParameterisationTrdY::GetMaxParameter() const
00329 {
00330 G4Trd* msol = (G4Trd*)(fmotherSolid);
00331 return 2*msol->GetYHalfLength1();
00332 }
00333
00334
00335 void
00336 G4ParameterisationTrdY::
00337 ComputeTransformation( const G4int copyNo, G4VPhysicalVolume* physVol ) const
00338 {
00339 G4Trd* msol = (G4Trd*)(fmotherSolid );
00340 G4double mdy = msol->GetYHalfLength1();
00341
00342
00343 G4ThreeVector origin(0.,0.,0.);
00344 G4double posi = -mdy + foffset + (copyNo+0.5)*fwidth;
00345
00346 if( faxis == kYAxis )
00347 {
00348 origin.setY( posi );
00349 }
00350 else
00351 {
00352 std::ostringstream message;
00353 message << "Only axes along Y are allowed ! Axis: " << faxis;
00354 G4Exception("G4ParameterisationTrdY::ComputeTransformation()",
00355 "GeomDiv0002", FatalException, message);
00356 }
00357
00358 #ifdef G4DIVDEBUG
00359 if( verbose >= 2 )
00360 {
00361 G4cout << std::setprecision(8)
00362 << " G4ParameterisationTrdY::ComputeTransformation " << copyNo
00363 << " pos " << origin << " rot mat " << " axis " << faxis << G4endl;
00364 }
00365 #endif
00366
00367
00368 physVol->SetTranslation( origin );
00369 }
00370
00371
00372 void
00373 G4ParameterisationTrdY::
00374 ComputeDimensions(G4Trd& trd, const G4int, const G4VPhysicalVolume*) const
00375 {
00376
00377
00378 G4Trd* msol = (G4Trd*)(fmotherSolid);
00379
00380 G4double pDx1 = msol->GetXHalfLength1();
00381 G4double pDx2 = msol->GetXHalfLength2();
00382 G4double pDz = msol->GetZHalfLength();
00383 G4double pDy = fwidth/2. - fhgap;
00384
00385 trd.SetAllParameters ( pDx1, pDx2, pDy, pDy, pDz );
00386
00387 #ifdef G4DIVDEBUG
00388 if( verbose >= 2 )
00389 {
00390 G4cout << " G4ParameterisationTrdY::ComputeDimensions():" << G4endl;
00391 trd.DumpInfo();
00392 }
00393 #endif
00394 }
00395
00396
00397 void G4ParameterisationTrdY::CheckParametersValidity()
00398 {
00399 G4VDivisionParameterisation::CheckParametersValidity();
00400
00401 G4Trd* msol = (G4Trd*)(fmotherSolid);
00402
00403 G4double mpDy1 = msol->GetYHalfLength1();
00404 G4double mpDy2 = msol->GetYHalfLength2();
00405
00406 if( std::fabs(mpDy1 - mpDy2) > kCarTolerance )
00407 {
00408 std::ostringstream message;
00409 message << "Invalid solid specification. NOT supported." << G4endl
00410 << "Making a division of a TRD along axis Y while" << G4endl
00411 << "the Y half lengths are not equal is not (yet)" << G4endl
00412 << "supported. It will result in non-equal" << G4endl
00413 << "division solids.";
00414 G4Exception("G4ParameterisationTrdY::CheckParametersValidity()",
00415 "GeomDiv0001", FatalException, message);
00416 }
00417 }
00418
00419
00420 G4ParameterisationTrdZ::
00421 G4ParameterisationTrdZ( EAxis axis, G4int nDiv,
00422 G4double width, G4double offset,
00423 G4VSolid* msolid, DivisionType divType )
00424 : G4VParameterisationTrd( axis, nDiv, width, offset, msolid, divType )
00425 {
00426 CheckParametersValidity();
00427 SetType( "DivTrdZ" );
00428
00429 G4Trd* msol = (G4Trd*)(fmotherSolid);
00430 if( divType == DivWIDTH )
00431 {
00432 fnDiv = CalculateNDiv( 2*msol->GetZHalfLength(),
00433 width, offset );
00434 }
00435 else if( divType == DivNDIV )
00436 {
00437 fwidth = CalculateWidth( 2*msol->GetZHalfLength(),
00438 nDiv, offset );
00439 }
00440
00441 #ifdef G4DIVDEBUG
00442 if( verbose >= 1 )
00443 {
00444 G4cout << " G4ParameterisationTrdZ no divisions " << fnDiv
00445 << " = " << nDiv << G4endl
00446 << " Offset " << foffset << " = " << offset << G4endl
00447 << " Width " << fwidth << " = " << width << G4endl;
00448 }
00449 #endif
00450 }
00451
00452
00453 G4ParameterisationTrdZ::~G4ParameterisationTrdZ()
00454 {
00455 }
00456
00457
00458 G4double G4ParameterisationTrdZ::GetMaxParameter() const
00459 {
00460 G4Trd* msol = (G4Trd*)(fmotherSolid);
00461 return 2*msol->GetZHalfLength();
00462 }
00463
00464
00465 void
00466 G4ParameterisationTrdZ::
00467 ComputeTransformation(const G4int copyNo, G4VPhysicalVolume *physVol) const
00468 {
00469 G4Trd* msol = (G4Trd*)(fmotherSolid );
00470 G4double mdz = msol->GetZHalfLength();
00471
00472
00473 G4ThreeVector origin(0.,0.,0.);
00474 G4double posi = -mdz + OffsetZ() + (copyNo+0.5)*fwidth;
00475 if( faxis == kZAxis )
00476 {
00477 origin.setZ( posi );
00478 }
00479 else
00480 {
00481 std::ostringstream message;
00482 message << "Only axes along Z are allowed ! Axis: " << faxis;
00483 G4Exception("G4ParameterisationTrdZ::ComputeTransformation()",
00484 "GeomDiv0002", FatalException, message);
00485 }
00486
00487 #ifdef G4DIVDEBUG
00488 if( verbose >= 1 )
00489 {
00490 G4cout << std::setprecision(8) << " G4ParameterisationTrdZ: "
00491 << copyNo << G4endl
00492 << " Position: " << origin << " - Offset: " << foffset
00493 << " - Width: " << fwidth << " Axis " << faxis << G4endl;
00494 }
00495 #endif
00496
00497
00498 physVol->SetTranslation( origin );
00499 }
00500
00501
00502 void
00503 G4ParameterisationTrdZ::
00504 ComputeDimensions(G4Trd& trd, const G4int copyNo,
00505 const G4VPhysicalVolume*) const
00506 {
00507
00508 G4Trd* msol = (G4Trd*)(fmotherSolid);
00509
00510 G4double pDx1 = msol->GetXHalfLength1();
00511 G4double DDx = (msol->GetXHalfLength2() - msol->GetXHalfLength1() );
00512 G4double pDy1 = msol->GetYHalfLength1();
00513 G4double DDy = (msol->GetYHalfLength2() - msol->GetYHalfLength1() );
00514 G4double pDz = fwidth/2. - fhgap;
00515 G4double zLength = 2*msol->GetZHalfLength();
00516
00517 trd.SetAllParameters( pDx1+DDx*(OffsetZ()+copyNo*fwidth+fhgap)/zLength,
00518 pDx1+DDx*(OffsetZ()+(copyNo+1)*fwidth-fhgap)/zLength,
00519 pDy1+DDy*(OffsetZ()+copyNo*fwidth+fhgap)/zLength,
00520 pDy1+DDy*(OffsetZ()+(copyNo+1)*fwidth-fhgap)/zLength,
00521 pDz );
00522
00523 #ifdef G4DIVDEBUG
00524 if( verbose >= 1 )
00525 {
00526 G4cout << " G4ParameterisationTrdZ::ComputeDimensions()"
00527 << " - Mother TRD " << G4endl;
00528 msol->DumpInfo();
00529 G4cout << " - Parameterised TRD: "
00530 << copyNo << G4endl;
00531 trd.DumpInfo();
00532 }
00533 #endif
00534 }