src/BDSBeamline.cc

00001 #include "BDSBeamline.hh"
00002 #include "G4AffineTransform.hh"
00003 
00004 BDSBeamline* BDSBeamline::_instance = 0;
00005 
00006 BDSBeamline* BDSBeamline::Instance(){
00007   if(_instance==0) {
00008     _instance = new BDSBeamline();
00009   }
00010   return _instance;
00011 
00012 }
00013 
00014 BDSBeamline::BDSBeamline(){
00015   _localX = new G4ThreeVector(1,0,0);
00016   _localY = new G4ThreeVector(0,1,0);
00017   _localZ = new G4ThreeVector(0,0,1);
00018   
00019   _rotationLocal = new G4RotationMatrix();
00020   _rotationGlobal = new G4RotationMatrix();
00021   _rotation = new G4RotationMatrix();
00022   
00023   _position = new G4ThreeVector(0,0,0);
00024   _positionStart = new G4ThreeVector(0,0,0);
00025   _positionEnd = new G4ThreeVector(0,0,0);
00026   _positionFromCurrentCenter = new G4ThreeVector(0,0,0);
00027   _zHalfAngle = new G4ThreeVector(0,0,0); 
00028 }
00029 
00030 BDSBeamline::~BDSBeamline(){
00031   for(first(); !isDone(); next()){
00032     delete *_iterComponent;
00033   }
00034   _componentList.clear();
00035 
00036   // todo: clear other lists
00037 
00038   delete _localX;
00039   delete _localY;
00040   delete _localZ;
00041   delete _rotationLocal;
00042   delete _rotationGlobal;
00043   delete _rotation;
00044   delete _position;
00045   delete _positionStart;
00046   delete _positionEnd;
00047   delete _positionFromCurrentCenter;
00048   delete _zHalfAngle;
00049 }
00050 
00051 void BDSBeamline::doNavigation(){
00052   //Reset the local rotation matrix
00053   *_rotationLocal = G4RotationMatrix();
00054   _s_local   = lastItem()->GetArcLength();
00055   _s_total += _s_local;
00056   G4double angle=lastItem()->GetAngle();
00057   G4double theta=lastItem()->GetTheta();
00058   G4double phi=lastItem()->GetPhi();
00059   G4double psi=lastItem()->GetPsi();
00060   G4double length=lastItem()->GetZLength();
00061   
00062   if( lastItem()->GetType() == "transform3d"){
00063     _rotationGlobal->rotate(psi,_localZ);
00064     _rotationLocal->rotate(psi,_localZ);
00065     _rotationGlobal->rotate(phi,_localY);   
00066     _rotationLocal->rotate(phi,_localY);
00067     _rotationGlobal->rotate(theta,_localX);
00068     _rotationLocal->rotate(theta,_localX);
00069     _localX->rotate(psi,*_localZ);
00070     _localY->rotate(psi,*_localZ);
00071     _localX->rotate(phi,*_localY);
00072     _localZ->rotate(phi,*_localY);
00073     _localY->rotate(theta,*_localX);
00074     _localZ->rotate(theta,*_localX);
00075   }
00076   
00077   // define center of bended elements from the previos coordinate frame
00078   _zHalfAngle->setX(_localZ->x());
00079   _zHalfAngle->setY(_localZ->y());
00080   _zHalfAngle->setZ(_localZ->z());
00081   if( lastItem()->GetType() == "sbend" || lastItem()->GetType() == "rbend"  )
00082     _zHalfAngle->rotate(angle/2,*_localY);
00083 
00084   
00085   // target position - advance the coordinates
00086 
00087     *_positionStart = (*_positionEnd);
00088     *_position = (*_positionEnd) + (*_zHalfAngle) * ( length/2 );  // The target position is the centre of the component.
00089     *_positionEnd = (*_position) + (*_zHalfAngle) * ( length/2 );  // The end position of the component.
00090     *_positionFromCurrentCenter = (*_position) - (*_positionEnd)/2.0; //The position of the beam line component from the centre of the CURRENT beam line
00091   
00092 
00093   // rotate to the previous reference frame
00094   _rotation->transform(*_rotationGlobal);
00095   _rotation->invert();
00096   // recompute global rotation
00097   // define new coordinate system local frame     
00098 
00099 
00100   
00101   // bends transform the coordinate system
00102   if( lastItem()->GetType() == "sbend" || lastItem()->GetType() == "rbend"){
00103     _rotationGlobal->rotate(angle,*_localY);
00104     _localX->rotate(angle,*_localY);
00105     _localZ->rotate(angle,*_localY);
00106     _rotationGlobal->rotate(theta,*_localX);
00107     _localY->rotate(theta,*_localX);
00108     _localZ->rotate(theta,*_localX);
00109     // bend trapezoids defined along z-axis
00110     _rotation->rotateY(-twopi/4-angle/2);                                               
00111   } else {
00112     // Transform3D has no Volumes:
00113     if (lastItem()->GetType() != "transform3d" && 
00114         lastItem()->GetMarkerLogicalVolume() && 
00115         lastItem()->GetMarkerLogicalVolume()->GetSolid() && 
00116         lastItem()->GetMarkerLogicalVolume()->GetSolid()->GetName().contains("trapezoid") ) {
00117       _rotation->rotateY(-twopi/4); //Drift trapezoids defined along z axis 
00118     }
00119   }
00120 
00121 
00122 
00123   _positionList.push_back(new G4ThreeVector(*_position));
00124   _positionStartList.push_back(new G4ThreeVector(*_positionStart));
00125   _positionEndList.push_back(new G4ThreeVector(*_positionEnd));
00126   _positionFromCurrentCenterList.push_back(new G4ThreeVector(*_positionFromCurrentCenter));
00127   _positionSList.push_back(_s_total);
00128   _rotationList.push_back(new G4RotationMatrix(*_rotation));
00129   _rotationGlobalList.push_back(new G4RotationMatrix(*_rotationGlobal));
00130   G4cout << "BDSBeamline::addComponent: finished." << G4endl;
00131 
00132   printNavigation();
00133 }
00134 
00135 void BDSBeamline::addComponent(BDSAcceleratorComponent* var){
00136   //Add component to the beamline
00137   G4cout << "BDSBeamline: adding component " << G4endl;
00138   _componentList.push_back(var);
00139   G4cout << "BDSBeamline: finished adding component. Setting as current item. " << G4endl;
00140   _iterComponent=_componentList.end();
00141   G4cout << "BDSBeamline: Set current item. " << G4endl;
00142   //Do the navigation
00143   doNavigation();
00144 
00145   G4cout << "Printing name. " << G4endl;
00146   G4cout << "BDSBeamline: " << lastItem()->GetName() << G4endl;
00147   //Update the reference transform
00148   setRefTransform(var);
00149 }
00150 
00151 void BDSBeamline::setRefTransform(BDSAcceleratorComponent* var){
00152   if(BDSGlobalConstants::Instance()->GetRefVolume()==var->GetName() && 
00153      BDSGlobalConstants::Instance()->GetRefCopyNo()==var->GetCopyNumber()){
00154     G4cout << "Setting new transform" <<G4endl;
00155     G4AffineTransform tf(rotationGlobal(),*positionStart());
00156     BDSGlobalConstants::Instance()->SetRefTransform(tf);
00157   }
00158 }
00159 
00160 void BDSBeamline::print(){
00161   for(first(); !isDone(); next()){
00162     G4cout << (*_iterComponent)->GetName() << G4endl;
00163     printNavigation();
00164   }
00165 
00166 
00167 }
00168 
00169 void BDSBeamline::printNavigation(){
00170   G4cout << "BDSBeamline: _position = " << *_position << G4endl;
00171   G4cout << "BDSBeamline: _rotation = " << *_rotation << G4endl;
00172 }
00173 
00174 BDSAcceleratorComponent* BDSBeamline::currentItem(){
00175   return *_iterComponent;
00176 }
00177 
00178 BDSAcceleratorComponent* BDSBeamline::lastItem(){
00179   if (_componentList.empty()) return NULL;
00180   _iterLastComponent=_componentList.end();
00181   _iterLastComponent--;
00182   return *_iterLastComponent;
00183 }
00184 
00185 G4int BDSBeamline::size(){
00186   return _componentList.size();
00187 }
00188 
00189 void BDSBeamline::first(){
00190   _iterComponent=_componentList.begin();
00191   //Navigation
00192   _iterRotation=_rotationList.begin();
00193   _iterRotationGlobal=_rotationGlobalList.begin();
00194   _iterPosition=_positionList.begin();
00195   _iterPositionStart=_positionStartList.begin();
00196   _iterPositionEnd=_positionEndList.begin();
00197   _iterPositionFromCurrentCenter=_positionFromCurrentCenterList.begin();
00198   _iterPositionS=_positionSList.begin();
00199 }
00200 
00201 bool BDSBeamline::isDone(){
00202   return (_iterComponent==_componentList.end());
00203 }
00204 
00205 void BDSBeamline::next(){
00206   _iterComponent++;
00207   //Navigation
00208   _iterRotation++;
00209   _iterRotationGlobal++;
00210   _iterPosition++;
00211   _iterPositionStart++;
00212   _iterPositionEnd++;
00213   _iterPositionFromCurrentCenter++;
00214   _iterPositionS++;
00215 
00216 }
00217 
00218 G4RotationMatrix* BDSBeamline::rotation(){
00219   return *_iterRotation;
00220 }
00221 
00222 G4RotationMatrix* BDSBeamline::rotationGlobal(){
00223   return *_iterRotationGlobal;
00224 }
00225 
00226 G4ThreeVector* BDSBeamline::position(){
00227   return *_iterPosition;
00228 }
00229 
00230 G4ThreeVector* BDSBeamline::positionStart(){
00231   return *_iterPositionStart;
00232 }
00233 
00234 G4ThreeVector* BDSBeamline::positionEnd(){
00235   return *_iterPositionEnd;
00236 }
00237 
00238 G4ThreeVector* BDSBeamline::positionFromCurrentCenter(){
00239   return *_iterPositionFromCurrentCenter;
00240 }
00241 
00242 G4double BDSBeamline::positionS(){
00243   return _positionS;
00244 }
00245 
00246 G4double BDSBeamline::s_total(){
00247   return _s_total;
00248 }

Generated on 27 Aug 2013 for BDSIM by  doxygen 1.4.7