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
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
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
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
00086
00087 *_positionStart = (*_positionEnd);
00088 *_position = (*_positionEnd) + (*_zHalfAngle) * ( length/2 );
00089 *_positionEnd = (*_position) + (*_zHalfAngle) * ( length/2 );
00090 *_positionFromCurrentCenter = (*_position) - (*_positionEnd)/2.0;
00091
00092
00093
00094 _rotation->transform(*_rotationGlobal);
00095 _rotation->invert();
00096
00097
00098
00099
00100
00101
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
00110 _rotation->rotateY(-twopi/4-angle/2);
00111 } else {
00112
00113 if (lastItem()->GetType() != "transform3d" &&
00114 lastItem()->GetMarkerLogicalVolume() &&
00115 lastItem()->GetMarkerLogicalVolume()->GetSolid() &&
00116 lastItem()->GetMarkerLogicalVolume()->GetSolid()->GetName().contains("trapezoid") ) {
00117 _rotation->rotateY(-twopi/4);
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
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
00143 doNavigation();
00144
00145 G4cout << "Printing name. " << G4endl;
00146 G4cout << "BDSBeamline: " << lastItem()->GetName() << G4endl;
00147
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
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
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 }