/scratch0/jsnuveri/BDSIM/BDSIMgit/bdsim/src/BDSElement.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: John C. Carter, Royal Holloway, Univ. of London.
00003    Last modified 02.12.2004
00004    Copyright (c) 2004 by J.C.Carter.  ALL RIGHTS RESERVED. 
00005 */
00006 
00007 #include "BDSAcceleratorComponent.hh"
00008 #include "BDSDebug.hh"
00009 #include "BDSExecOptions.hh"
00010 #include "BDSElement.hh"
00011 #include "BDSGlobalConstants.hh"
00012 #include "BDS3DMagField.hh"
00013 #include "BDSXYMagField.hh"
00014 #include "BDSMagFieldSQL.hh"
00015 #include "G4Box.hh"
00016 #include "G4Tubs.hh"
00017 #include "G4Torus.hh"
00018 #include "G4Trd.hh"
00019 #include "G4VisAttributes.hh"
00020 #include "G4LogicalVolume.hh"
00021 #include "G4VPhysicalVolume.hh"
00022 #include "G4PVPlacement.hh"
00023 #include "G4UserLimits.hh"
00024 #include "G4Mag_UsualEqRhs.hh"
00025 
00026 #include "G4NystromRK4.hh"
00027 
00028 // geometry drivers
00029 #include "ggmad.hh"
00030 #include "BDSGeometrySQL.hh"
00031 
00032 #ifdef USE_LCDD
00033 #include "BDSGeometryLCDD.hh"
00034 #endif
00035 
00036 #ifdef USE_GDML
00037 #include "BDSGeometryGDML.hh"
00038 #endif
00039 
00040 #include <vector>
00041 
00042 class BDSTiltOffset;
00043 
00044 BDSElement::BDSElement(G4String      name,
00045                        G4double      length,
00046                        G4String      geometry,
00047                        G4String      bmap,
00048                        G4double      bmapZOffset,
00049                        BDSTiltOffset tiltOffset):
00050   BDSAcceleratorComponent(name, length, 0, "element", tiltOffset),
00051   itsGeometry(geometry), itsBmap(bmap),
00052   fChordFinder(NULL), itsFStepper(NULL), itsFEquation(NULL), itsEqRhs(NULL), 
00053   itsMagField(NULL), itsCachedMagField(NULL), itsUniformMagField(NULL)
00054 {
00055   itsFieldVolName="";
00056   itsFieldIsUniform=false;
00057   itsBmapZOffset = bmapZOffset;
00058 
00059   // WARNING: ALign in and out will only apply to the first instance of the
00060   //          element. Subsequent copies will have no alignment set.
00061   align_in_volume = NULL;
00062   align_out_volume = NULL;
00063 }
00064 
00065 void BDSElement::BuildContainerLogicalVolume()
00066 {
00067 #ifdef BDSDEBUG 
00068   G4cout << __METHOD_NAME__ << " building geometry of element named: \""
00069          << name << "\"" << G4endl;
00070 #endif
00071   BuildGeometry(); // build element box
00072       
00073 #ifdef BDSDEBUG 
00074   G4cout << __METHOD_NAME__ << "completed geometry construction " << G4endl;
00075 #endif
00076 
00077   PlaceComponents(itsGeometry,itsBmap); // place components (from file) and build filed maps
00078 }
00079 
00080 void BDSElement::BuildElementMarkerLogicalVolume()
00081 {  
00082 #ifdef BDSDEBUG 
00083   G4cout << __METHOD_NAME__ <<G4endl;
00084 #endif
00085   // TBC these really needs to be done automatically
00086   // for now the geometry is constructed after the "marker" / container
00087   // volume so it can be place inside - but how do we know how big it is?
00088   G4double outerDiameter = 10*CLHEP::m;
00089   G4double elementSizeX = outerDiameter*0.5 + lengthSafety;
00090   G4double elementSizeY = outerDiameter*0.5 + lengthSafety;
00091 
00092   G4double elementSize=std::max(elementSizeX, elementSizeY); 
00093   
00094   containerSolid = new G4Box(name + "_container_solid",
00095                              elementSize,
00096                              elementSize,   
00097                              chordLength*0.5);
00098   
00099   containerLogicalVolume = new G4LogicalVolume(containerSolid,
00100                                                emptyMaterial,
00101                                                name + "_container_lv");
00102 
00103 #ifdef BDSDEBUG 
00104   G4cout << __METHOD_NAME__ << "container volume dimensions: x, y = "<< elementSize/CLHEP::m
00105          <<" m, l = "<<  chordLength/CLHEP::m <<" m"<<G4endl;
00106 #endif
00107 
00108 
00109     //-----------------------------
00110     /*
00111       G4RotationMatrix* rotMatrix1 = new G4RotationMatrix();
00112   rotMatrix1->rotateY(itsPhiAngleIn);
00113   G4RotationMatrix* rotMatrix2 = new G4RotationMatrix();
00114   rotMatrix1->rotateY(itsPhiAngleOut);
00115   G4ThreeVector transVec1(0, 0, itsLength
00116 
00117   containerLogicalVolume = new G4SubtactionSolid(itsName+"_generic_element",
00118                                                  new G4SubtactionSolid(itsName+"_tempSolid1",
00119                                                                        new G4Box(itsName+"tempSolid1a",
00120                                                                                  elementSize,
00121                                                                                  elementSize,   
00122                                                                                  itsLength/2),
00123                                                                        new G4Box(itsName+"tempSolid1b", 
00124                                                                                  sin(itsPhiAngleIn)*elementSize*2, //Make sure it is wider than the solid being subtracted from
00125                                                                                  elementSize,
00126                                                                                  itsLength/2),
00127                                                                        rotMatrix1,
00128                                                                        transVec1),
00129                                                  new  G4Box(itsName+"tempSolid2", 
00130                                                             sin(itsPhiAngleOut)*elementSize*2, //Make sure it is wider than the solid being subtracted from
00131                                                             elementSize,
00132                                                             itsLength/2),
00133                                                  rotMatrix2,
00134                                                  transVec2);
00135 
00136 
00137 
00138   G4LogicalVolume* tempBox1 = new G4LogicalVolume(new G4Box(itsName+"tempBox1", 
00139                                                             sin(itsPhiAngleIn)*elementSize,
00140                                                             elementSize,
00141                                                             itsLength/2),
00142                                                   BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),
00143                                                   itsName+"tempBox1Log"
00144                                                   );
00145   
00146 
00147     */
00148 
00149   /*
00150   G4double xHalfLengthPlus, xHalfLengthMinus;
00151   xHalfLengthMinus = (itsLength + (elementSize/2.0)*(tan(itsPhiAngleIn) -tan(itsPhiAngleOut)))/2.0;
00152   xHalfLengthPlus = (itsLength +  (elementSize/2.0)*(tan(itsPhiAngleOut)-tan(itsPhiAngleIn )))/2.0;
00153   
00154   
00155   containerSolid = new G4Trd(itsName+"_marker",
00156                                    xHalfLengthPlus,     // x hlf lgth at +z
00157                                    xHalfLengthMinus,    // x hlf lgth at -z
00158                                    elementSize/2,           // y hlf lgth at +z
00159                                    elementSize/2,           // y hlf lgth at -z
00160                                    fabs(cos(itsAngle/2))*elementSize/2);// z hlf lgth
00161   
00162   G4String LocalLogicalName=itsName;
00163   
00164   containerLogicalVolume=    
00165     new G4LogicalVolume(containerSolid,
00166                         BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),
00167                         LocalLogicalName+"_marker");
00168   */
00169   
00170   G4UserLimits* itsMarkerUserLimits = new G4UserLimits(DBL_MAX,DBL_MAX,DBL_MAX, BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00171   G4double  maxStepFactor=5;
00172   itsMarkerUserLimits->SetMaxAllowedStep(chordLength*maxStepFactor);
00173   containerLogicalVolume->SetUserLimits(itsMarkerUserLimits);
00174   
00175   
00176   //
00177   // zero field in the marker volume
00178   //
00179   containerLogicalVolume->
00180     SetFieldManager(BDSGlobalConstants::Instance()->GetZeroFieldManager(),false);
00181 }
00182 
00183 void BDSElement::BuildGeometry()
00184 {
00185   // multiple element instances not implemented yet!!!
00186 
00187   // Build the marker logical volume 
00188   BuildElementMarkerLogicalVolume();
00189 
00190 #ifndef NOUSERLIMITS
00191   G4UserLimits* itsOuterUserLimits = new G4UserLimits();
00192   G4double stepfactor=5;
00193   itsOuterUserLimits->SetMaxAllowedStep(chordLength*stepfactor);
00194   itsOuterUserLimits->SetUserMaxTime(BDSGlobalConstants::Instance()->GetMaxTime());
00195   if(BDSGlobalConstants::Instance()->GetThresholdCutCharged()>0){
00196     itsOuterUserLimits->SetUserMinEkine(BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00197   }
00198   containerLogicalVolume->SetUserLimits(itsOuterUserLimits);
00199 #endif
00200 }
00201 
00202 // place components 
00203 void BDSElement::PlaceComponents(G4String geometry, G4String bmap)
00204 {
00205 
00206   G4String gFormat="", bFormat="";
00207   G4String gFile="", bFile="";
00208 
00209   // get geometry format and file
00210   if(geometry != ""){
00211     G4int pos = geometry.find(":");
00212     gFormat="none";
00213     if(pos<0) { 
00214       G4cerr<<"WARNING: invalid geometry reference format : "<<geometry<<G4endl;
00215     }
00216     else {
00217       gFormat = geometry.substr(0,pos);
00218       gFile = BDSExecOptions::Instance()->GetBDSIMPATH() + geometry.substr(pos+1,geometry.length() - pos);     
00219     }
00220   }
00221 
00222   // get fieldmap format and file
00223   bFormat="none";
00224   if(bmap != ""){
00225     G4int pos = bmap.find(":");
00226     if(pos<0) {
00227       G4cerr<<"WARNING: invalid B map reference format : "<<bmap<<G4endl;
00228     }
00229     else {
00230       bFormat = bmap.substr(0,pos);
00231       bFile = BDSExecOptions::Instance()->GetBDSIMPATH() + bmap.substr(pos+1,bmap.length() - pos); 
00232 #ifdef BDSDEBUG
00233       G4cout << "BDSElement::PlaceComponents bmap file is " << bFile << G4endl;
00234 #endif
00235     }
00236   }
00237 
00238 #ifdef BDSDEBUG
00239   G4cout<<"placing components:\n geometry format - "<<gFormat<<G4endl<<
00240     "file - "<<gFile<<G4endl;
00241   G4cout<<"bmap format - "<<bFormat<<G4endl<<
00242     "file - "<<bFile<<G4endl;
00243 #endif
00244 
00245 
00246   // get the geometry for the driver
00247   // different drivers may interpret the fieldmap differently
00248   // so a field map without geometry is not allowed
00249 
00250   if(gFormat=="gmad") {
00251     GGmadDriver *ggmad = new GGmadDriver(gFile);
00252     ggmad->Construct(containerLogicalVolume);
00253 
00254     // set sensitive volumes
00255     // RegisterSensitiveVolumes(ggmad->SensitiveComponents);
00256     RegisterSensitiveVolume(containerLogicalVolume);
00257 
00258     // attach magnetic field if present
00259     if(bFormat=="3D"){
00260 #ifdef BDSDEBUG
00261       G4cout << "BDSElement.cc> Making BDS3DMagField..." << G4endl;
00262 #endif
00263       
00264       itsMagField = new BDS3DMagField(bFile, itsBmapZOffset);
00265       itsCachedMagField = new G4CachedMagneticField(itsMagField, 1*CLHEP::um);
00266       BuildMagField(true);
00267     }else if(bFormat=="XY"){
00268       itsMagField = new BDSXYMagField(bFile);
00269       itsCachedMagField = new G4CachedMagneticField(itsMagField, 1*CLHEP::um);
00270 
00271       // build the magnetic field manager and transportation
00272       BuildMagField(true);
00273     }
00274     delete ggmad;
00275   }
00276   else if(gFormat=="lcdd") {
00277 #ifdef USE_LCDD
00278     BDSGeometryLCDD *LCDD = new BDSGeometryLCDD(gFile);
00279     //Make marker visible (temp debug)
00280     G4VisAttributes* VisAttLCDD = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0));
00281     VisAttLCDD->SetForceSolid(true);  
00282     VisAttLCDD->SetVisibility(false);
00283     containerLogicalVolume->SetVisAttributes(VisAttLCDD);
00284 
00285     LCDD->Construct(containerLogicalVolume);
00286     RegisterSensitiveVolume(containerLogicalVolume);
00287     if(bFormat=="XY"){
00288       itsMagField = new BDSXYMagField(bFile);
00289       itsCachedMagField = new G4CachedMagneticField(itsMagField, 1*CLHEP::um);
00290 
00291       // build the magnetic field manager and transportation
00292       BuildMagField(true);
00293     } else if ( bFormat == "mokka" ){
00294       G4ThreeVector uniField = G4ThreeVector(0,3.5*CLHEP::tesla,0);
00295       std::vector<G4ThreeVector> uniFieldVect;
00296       uniFieldVect.push_back(uniField);
00297       std::vector<G4double> nulld;
00298       std::vector<G4String> nulls;
00299       //      itsMagField = new BDSMagFieldSQL(bFile,itsLength,nulls, nulld, nulls, nulld, nulls, nulld, LCDD->FieldVol, uniFieldVect);
00300     } else if ( bFormat == "test" ){
00301     }
00302     else if ( bFormat == "none" ){
00303       itsFieldIsUniform=LCDD->GetFieldIsUniform();
00304       if(itsFieldIsUniform){
00305         G4cout << "BDSElement> using LCDD format uniform field..." << G4endl;
00306         itsUniformMagField=LCDD->GetUniformField();
00307       }else{
00308         itsMagField=LCDD->GetField();
00309         itsCachedMagField = new G4CachedMagneticField(itsMagField, 1*CLHEP::um);
00310         
00311       }
00312       itsFieldVolName=LCDD->GetFieldVolName();
00313       BuildMagField(true);
00314     }
00315 
00316     RegisterSensitiveVolumes(LCDD->SensitiveComponents);
00317     delete LCDD;
00318 #else
00319     G4cout << "LCDD support not selected during BDSIM configuration" << G4endl;
00320     G4Exception("Please re-compile BDSIM with USE_LCDD flag", "-1", FatalException, "");
00321 #endif
00322   }
00323   else if(gFormat=="mokka") {
00324 #ifdef BDSDEBUG
00325     G4cout << "BDSElement.cc: loading geometry sql file: BDSGeometrySQL(" << gFile << "," << chordLength << ")" << G4endl;
00326 #endif
00327     BDSGeometrySQL *Mokka = new BDSGeometrySQL(gFile,chordLength,containerLogicalVolume);
00328     for(unsigned int i=0; i<Mokka->GetMultiplePhysicalVolumes().size(); i++){
00329       SetMultiplePhysicalVolumes(Mokka->GetMultiplePhysicalVolumes().at(i));
00330     }
00331 
00332     RegisterSensitiveVolumes(Mokka->SensitiveComponents);
00333 
00334     std::vector<G4LogicalVolume*> GFlashComps =Mokka->itsGFlashComponents;
00335     for(G4int id=0; id<(G4int)GFlashComps.size(); id++)
00336       SetGFlashVolumes(GFlashComps[id]);
00337 
00338     align_in_volume = Mokka->align_in_volume;
00339     align_out_volume = Mokka->align_out_volume;
00340     // attach magnetic field if present
00341 
00342     if(bFormat=="3D"){
00343 #ifdef BDSDEBUG
00344       G4cout << "BDSElement.cc> Making BDS3DMagField..." << G4endl;
00345 #endif
00346       itsMagField = new BDS3DMagField(bFile, 0);
00347       itsCachedMagField = new G4CachedMagneticField(itsMagField, 1*CLHEP::um);
00348       
00349       BuildMagField(true);
00350     } else if(bFormat=="XY"){
00351       itsMagField = new BDSXYMagField(bFile);
00352       itsCachedMagField = new G4CachedMagneticField(itsMagField, 1*CLHEP::um);
00353       
00354       // build the magnetic field manager and transportation
00355       BuildMagField(true);
00356     } else if(bFormat=="mokka" || bFormat=="none")
00357       {
00358         if(Mokka->HasFields || bFile!="")
00359           // Check for field file or volumes with fields
00360           // as there may be cases where there are no bFormats given
00361           // in gmad file but fields might be set to volumes in SQL files
00362           {
00363             itsMagField = new BDSMagFieldSQL(bFile,chordLength,
00364                                              Mokka->QuadVolBgrad,
00365                                              Mokka->SextVolBgrad,
00366                                              Mokka->OctVolBgrad,
00367                                              Mokka->UniformFieldVolField,
00368                                              Mokka->nPoleField,
00369                                              Mokka->HasUniformField);
00370             itsCachedMagField = new G4CachedMagneticField(itsMagField, 1*CLHEP::um);
00371 
00372             
00373             // build the magnetic field manager and transportation
00374             BuildMagField(true);
00375           }
00376       }
00377     delete Mokka;
00378   }
00379   else if(gFormat=="gdml") {
00380 #ifdef USE_GDML
00381     BDSGeometryGDML *GDML = new BDSGeometryGDML(gFile);
00382     GDML->Construct(containerLogicalVolume);
00383     delete GDML;
00384 #else
00385     G4cout << "GDML support not selected during BDSIM configuration" << G4endl;
00386     G4Exception("Please re-compile BDSIM with USE_GDML flag", "-1", FatalException, "");
00387 #endif
00388   }
00389   else {
00390     G4cerr<<"geometry format "<<gFormat<<" not supported"<<G4endl;
00391   }
00392 }
00393 
00394 void BDSElement::BuildMagField(G4bool forceToAllDaughters)
00395 {
00396 #ifdef BDSDEBUG
00397   G4cout << "BDSElement.cc::BuildMagField Building magnetic field...." << G4endl;
00398 #endif
00399   // create a field manager
00400   G4FieldManager* fieldManager = new G4FieldManager();
00401 
00402 
00403   if(!itsFieldIsUniform){
00404 #ifdef BDSDEBUG
00405     G4cout << "BDSElement.cc> Building magnetic field..." << G4endl;
00406 #endif
00407     itsEqRhs = new G4Mag_UsualEqRhs(itsCachedMagField);
00408     if( (itsMagField->GetHasUniformField())&!(itsMagField->GetHasNPoleFields() || itsMagField->GetHasFieldMap())){
00409       itsFStepper = new G4NystromRK4(itsEqRhs); 
00410     } else {
00411       itsFStepper = new G4NystromRK4(itsEqRhs);
00412     }
00413     fieldManager->SetDetectorField(itsCachedMagField );
00414   } else {
00415 #ifdef BDSDEBUG
00416     G4cout << "BDSElement.cc> Building uniform magnetic field..." << G4endl;
00417 #endif
00418     itsEqRhs = new G4Mag_UsualEqRhs(itsUniformMagField);
00419     itsFStepper = new G4NystromRK4(itsEqRhs); 
00420     fieldManager->SetDetectorField(itsUniformMagField );
00421   }
00422 
00423 #ifdef BDSDEBUG
00424   G4cout << "BDSElement.cc> Setting stepping accuracy parameters..." << G4endl;
00425 #endif
00426   
00427   if(BDSGlobalConstants::Instance()->GetDeltaOneStep()>0){
00428     fieldManager->SetDeltaOneStep(BDSGlobalConstants::Instance()->GetDeltaOneStep());
00429   }
00430   if(BDSGlobalConstants::Instance()->GetMaximumEpsilonStep()>0){
00431     fieldManager->SetMaximumEpsilonStep(BDSGlobalConstants::Instance()->GetMaximumEpsilonStep());
00432   }
00433   if(BDSGlobalConstants::Instance()->GetMinimumEpsilonStep()>=0){
00434     fieldManager->SetMinimumEpsilonStep(BDSGlobalConstants::Instance()->GetMinimumEpsilonStep());
00435   }
00436   if(BDSGlobalConstants::Instance()->GetDeltaIntersection()>0){
00437     fieldManager->SetDeltaIntersection(BDSGlobalConstants::Instance()->GetDeltaIntersection());
00438   }
00439 
00440   G4MagInt_Driver* fIntgrDriver = new G4MagInt_Driver(BDSGlobalConstants::Instance()->GetChordStepMinimum(),
00441                                                       itsFStepper, 
00442                                                       itsFStepper->GetNumberOfVariables() );
00443   fChordFinder = new G4ChordFinder(fIntgrDriver);
00444   
00445   fChordFinder->SetDeltaChord(BDSGlobalConstants::Instance()->GetDeltaChord());
00446   
00447   fieldManager->SetChordFinder( fChordFinder ); 
00448   
00449 #ifdef BDSDEBUG
00450   G4cout << "BDSElement.cc> Setting the logical volume " << containerLogicalVolume->GetName() << " field manager... force to all daughters = " << forceToAllDaughters << G4endl;
00451 #endif
00452   containerLogicalVolume->SetFieldManager(fieldManager,forceToAllDaughters);
00453 }
00454 
00455 // creates a field mesh in the reference frame of a physical volume
00456 // from  b-field map value list 
00457 // has to be called after the component is placed in the geometry
00458 void BDSElement::PrepareField(G4VPhysicalVolume *referenceVolume)
00459 {
00460   if(!itsMagField) return;
00461   itsMagField->Prepare(referenceVolume);
00462   itsCachedMagField = new G4CachedMagneticField(itsMagField, 1*CLHEP::um);
00463 }
00464 
00465 // Rotates and positions the marker volume before it is placed in
00466 // BDSDetectorConstruction. It aligns the marker volume so that the
00467 // the beamline goes through the specified daugther volume (e.g. for mokka)
00468 void BDSElement::AlignComponent(G4ThreeVector& TargetPos, 
00469                                 G4RotationMatrix *TargetRot, 
00470                                 G4RotationMatrix& globalRotation,
00471                                 G4ThreeVector& rtot,
00472                                 G4ThreeVector& rlast,
00473                                 G4ThreeVector& localX,
00474                                 G4ThreeVector& localY,
00475                                 G4ThreeVector& localZ)
00476 {
00477   
00478   
00479   if(align_in_volume == NULL)
00480     {
00481       if(align_out_volume == NULL)
00482         {
00483           // advance co-ords in usual way if no alignment volumes found
00484           
00485           rtot = rlast + localZ*(chordLength/2);
00486           rlast = rtot + localZ*(chordLength/2);
00487           return;
00488         }
00489       else 
00490         {
00491 #ifdef BDSDEBUG
00492           G4cout << "BDSElement : Aligning outgoing to SQL element " 
00493                  << align_out_volume->GetName() << G4endl;
00494 #endif
00495           G4RotationMatrix Trot = *TargetRot;
00496           G4RotationMatrix trackedRot;
00497           G4RotationMatrix outRot = *(align_out_volume->GetFrameRotation());
00498           trackedRot.transform(outRot.inverse());
00499           trackedRot.transform(Trot.inverse());
00500           globalRotation = trackedRot;
00501 
00502           G4ThreeVector outPos = align_out_volume->GetFrameTranslation();
00503           G4ThreeVector diff = outPos;
00504 
00505           G4ThreeVector zHalfAngle = G4ThreeVector(0.,0.,1.);
00506 
00507           zHalfAngle.transform(globalRotation);
00508 
00509           //moving positioning to outgoing alignment volume
00510           rlast = TargetPos - ((outPos.unit()).transform(Trot.inverse()) )*diff.mag();
00511           localX.transform(outRot.inverse());
00512           localY.transform(outRot.inverse());
00513           localZ.transform(outRot.inverse());
00514 
00515           localX.transform(Trot.inverse());
00516           localY.transform(Trot.inverse());
00517           localZ.transform(Trot.inverse());
00518 
00519           //moving position in Z be at least itsLength/2 away
00520           rlast +=zHalfAngle*(chordLength/2 + diff.z());
00521           return;
00522         }
00523     }
00524 
00525   if(align_in_volume != NULL)
00526     {
00527 #ifdef BDSDEBUG
00528       G4cout << "BDSElement : Aligning incoming to SQL element " 
00529              << align_in_volume->GetName() << G4endl;
00530 #endif
00531       
00532       const G4RotationMatrix* inRot = align_in_volume->GetFrameRotation();
00533       TargetRot->transform((*inRot).inverse());
00534       
00535       G4ThreeVector inPos = align_in_volume->GetFrameTranslation();
00536       inPos.transform((*TargetRot).inverse());
00537       TargetPos+=G4ThreeVector(inPos.x(), inPos.y(), 0.0);
00538       
00539       if(align_out_volume == NULL)
00540         {
00541           // align outgoing (i.e. next component) to Marker Volume
00542           
00543           G4RotationMatrix Trot = *TargetRot;
00544           globalRotation.transform(Trot.inverse());
00545           
00546           G4ThreeVector zHalfAngle = G4ThreeVector(0.,0.,1.);
00547           zHalfAngle.transform(Trot.inverse());
00548           
00549           rlast = TargetPos + zHalfAngle*(chordLength/2);
00550           localX.transform(Trot.inverse());
00551           localY.transform(Trot.inverse());
00552           localZ.transform(Trot.inverse());
00553           return;
00554         }
00555 
00556       else
00557         {
00558 #ifdef BDSDEBUG
00559           G4cout << "BDSElement : Aligning outgoing to SQL element " 
00560                  << align_out_volume->GetName() << G4endl;
00561 #endif
00562           G4RotationMatrix Trot = *TargetRot;
00563           G4RotationMatrix trackedRot;
00564           G4RotationMatrix outRot = *(align_out_volume->GetFrameRotation());
00565           trackedRot.transform(outRot.inverse());
00566           trackedRot.transform(Trot.inverse());
00567           globalRotation = trackedRot;
00568 
00569           G4ThreeVector outPos = align_out_volume->GetFrameTranslation();
00570           G4ThreeVector diff = outPos;
00571 
00572           G4ThreeVector zHalfAngle = G4ThreeVector(0.,0.,1.);
00573 
00574           zHalfAngle.transform(globalRotation);
00575 
00576           //moving positioning to outgoing alignment volume
00577           rlast = TargetPos - ((outPos.unit()).transform(Trot.inverse()) )*diff.mag();
00578           localX.transform(outRot.inverse());
00579           localY.transform(outRot.inverse());
00580           localZ.transform(outRot.inverse());
00581 
00582           localX.transform(Trot.inverse());
00583           localY.transform(Trot.inverse());
00584           localZ.transform(Trot.inverse());
00585 
00586           //moving position in Z be at least itsLength/2 away
00587           rlast +=zHalfAngle*(chordLength/2 + diff.z());
00588           return;
00589         }
00590     }
00591 }
00592 
00593 BDSElement::~BDSElement()
00594 {
00595   delete fChordFinder;
00596   delete itsFStepper;
00597   delete itsFEquation;
00598 }

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7