BLCoordinates::ReferenceCoordinates Class Reference

Inheritance diagram for BLCoordinates::ReferenceCoordinates:

BLManager::TrackingAction BLManager::SteppingAction

List of all members.

Public Member Functions

 ReferenceCoordinates ()
virtual ~ReferenceCoordinates ()
void PreUserTrackingAction (const G4Track *track)
void PostUserTrackingAction (const G4Track *track)
void UserSteppingAction (const G4Step *step)
void addStep (const G4ThreeVector &pos, G4double z, bool final=false)

Private Attributes

BLManagermanager
G4ThreeVector prevDir
G4double prevZ
G4ThreeVector prevPos
G4double stepZ
G4ThreeVector stepPos
G4ThreeVector prevStepPos

Static Private Attributes

static G4ThreeVector unitZ


Constructor & Destructor Documentation

BLCoordinates::ReferenceCoordinates::ReferenceCoordinates (  ) 

virtual BLCoordinates::ReferenceCoordinates::~ReferenceCoordinates (  )  [inline, virtual]

00040 { }


Member Function Documentation

void BLCoordinates::ReferenceCoordinates::PreUserTrackingAction ( const G4Track *  track  )  [virtual]

Implements BLManager::TrackingAction.

References BEAM, BLCOORD_CENTERLINE, BLCoordinates::getCoords(), BLManager::getObject(), BLCoordinates::isValid(), prevDir, prevPos, prevStepPos, prevZ, REFERENCE, BLCoordinates::segmentRC, BLCoordinates::setMostRecentReferenceZ(), stepPos, stepZ, and BLCoordinates::validRC.

00465 {
00466         BLCoordinates *coord = (BLCoordinates *)track->GetUserInformation();
00467         if(!coord || !coord->isValid()) {
00468                 G4Exception("BLCoordinates","Coordinate Object Missing in Reference Track",
00469                                                         FatalException, "");
00470         }
00471 
00472         coord->segmentRC = 99999999;
00473 
00474         if(BLManager::getObject()->getState() == BEAM) {
00475                 if(!validRC) {
00476                         G4Exception("BLCoordinates","Reference Coordinates not available",
00477                                                         FatalException, "");
00478                 }
00479                 return;
00480         }
00481 
00482         if(BLManager::getObject()->getState() != REFERENCE) return;
00483 
00484         // @@@ need to handle multiple reference particles !!!!
00485 
00486         prevPos = track->GetPosition();
00487         prevDir = track->GetMomentumDirection();
00488 
00489         // initial Z is same as Centerline Coord value.
00490         G4ThreeVector cl;
00491         coord->getCoords(BLCOORD_CENTERLINE,cl);
00492         prevZ = cl[2];
00493         coord->setMostRecentReferenceZ(prevZ);
00494 
00495         // fake initial step of 1 mm 
00496         // (ensures sanity if reference bends in first step)
00497         stepPos = prevPos - prevDir;
00498         prevStepPos = stepPos - prevDir;
00499         stepZ = prevZ - 1.0;
00500 }

void BLCoordinates::ReferenceCoordinates::PostUserTrackingAction ( const G4Track *  track  )  [virtual]

Implements BLManager::TrackingAction.

References addStep(), BLManager::getObject(), BLCoordinates::global, REFERENCE, BLCoordinates::segmentRCVector, and BLCoordinates::validRC.

00503 {
00504         if(BLManager::getObject()->getState() != REFERENCE) return;
00505 
00506         // add 1 mm to final step
00507         // (ensures sanity if reference bends in final step)
00508         G4ThreeVector pos = track->GetPosition()+track->GetMomentumDirection();
00509         G4double z = track->GetTrackLength() + 1.0;
00510         addStep(pos,z,true);
00511 
00512         validRC = true;
00513 
00514         // for debugging -- dump segmentRCVector
00515         printf("\n# segmentRCVector\n#N minZ maxZ globX globY globZ axisX axisY axisZ angleDeg corr\n");
00516         G4double local[4];
00517         local[0] = local[1] = local[2] = local[3] = 0.0;
00518         for(unsigned i=0; i<segmentRCVector.size(); ++i) {
00519                 G4double global[4];
00520                 local[2] = (i==0 ? 0.0 : segmentRCVector[i].minZ);
00521                 segmentRCVector[i].transform.getGlobal(local,global);
00522                 G4ThreeVector axis = 
00523                         segmentRCVector[i].transform.getRotation().getAxis();
00524                 printf("%d %.4g %.4g %.4g %.4g %.4g %.4f %.4f %.4f %.1f %.3f\n",i,
00525                         segmentRCVector[i].minZ,segmentRCVector[i].maxZ,
00526                         global[0],global[1],global[2],axis[0],axis[1],axis[2],
00527                         segmentRCVector[i].transform.getRotation().getDelta()/deg,
00528                         segmentRCVector[i].correction);
00529         }
00530         printf("\n");
00531         fflush(stdout);
00532 }

void BLCoordinates::ReferenceCoordinates::UserSteppingAction ( const G4Step *  step  )  [virtual]

Implements BLManager::SteppingAction.

References addStep(), BLManager::getObject(), prevDir, prevPos, prevZ, REFERENCE, BLCoordinates::setMostRecentReferenceZ(), and BLCoordinates::tolerance.

00535 {
00536         // handle all states
00537         if(BLManager::getObject()->getState() != REFERENCE) return;
00538 
00539         G4Track *track = step->GetTrack();
00540         G4ThreeVector dir = track->GetMomentumDirection();
00541         if((dir-prevDir).mag2() > tolerance*tolerance)
00542                 addStep(prevPos, prevZ);
00543 
00544         prevDir = dir;
00545         prevPos = track->GetPosition();
00546         prevZ = track->GetTrackLength();
00547         BLCoordinates::setMostRecentReferenceZ(prevZ);
00548 }

void BLCoordinates::ReferenceCoordinates::addStep ( const G4ThreeVector &  pos,
G4double  z,
bool  final = false 
)

References BLCoordinates::currentCL, M_PI, prevStepPos, BLCoordinates::segmentCLVector, BLCoordinates::segmentRCVector, stepPos, stepZ, BLCoordinates::tolerance, and unitZ.

Referenced by PostUserTrackingAction(), and UserSteppingAction().

00552 {
00553         G4ThreeVector delta = pos - stepPos;
00554         G4double magDelta = delta.mag();
00555 
00556         // protect against delta being too small (should never happen,
00557         // as momentum direction changed significantly or first/final step
00558         // is >= 1 mm).
00559         if(magDelta < tolerance) return;
00560 
00561         // logic for rings is in CL coordinates; when we are lost, use CL
00562         // segment as starting point
00563         if(segmentCLVector[currentCL].firstRCSegment > segmentRCVector.size())
00564                 segmentCLVector[currentCL].firstRCSegment = 
00565                                                         segmentRCVector.size();
00566 
00567         G4ThreeVector rot = unitZ.cross(delta.unit());
00568         G4double a = asin(rot.mag());
00569         rot = rot.unit();
00570         // handle all 4 quadrants
00571         G4double b = unitZ.dot(delta.unit());
00572         if(a >= 0.0) {
00573                 if(b >= 0.0)
00574                         a = a;
00575                 else
00576                         a = M_PI - a;
00577         } else {
00578                 if(b >= 0.0)
00579                         a = a;
00580                 else
00581                         a = -M_PI + a;
00582         }
00583 
00584         G4RotationMatrix *p = 0;
00585         if(a > tolerance)
00586                 p = new G4RotationMatrix(rot,a);
00587         G4ThreeVector tmp(0,0,-stepZ);
00588         if(p)
00589                 tmp = *p * tmp;
00590         tmp += stepPos;
00591 
00592         G4double minZ = (segmentRCVector.size()==0 ? -DBL_MAX : stepZ);
00593         G4double maxZ = (final ? DBL_MAX : z);
00594         G4double interpPrev = stepZ + (z-stepZ)/4.0;
00595         G4double interpThis = z - (z-stepZ)/4.0;
00596         G4double correction = (z-stepZ)/magDelta;
00597 //printf("addStep minZ=%.4g maxZ=%.4g start x,y,z=%.3f,%.3f,%.3f  axis=%.3f,%.3f,%.3f aDeg=%.1f  corr=%.6f\n",minZ,maxZ,stepPos.x(),stepPos.y(),stepPos.z(),rot[0],rot[1],rot[2],a/deg,correction);
00598         segmentRCVector.push_back(RCSegment(minZ,maxZ,
00599                 BLCoordinateTransform(p,tmp),correction,interpPrev,interpThis));
00600 
00601         // set previous interpolate
00602         if(segmentRCVector.size() >= 2) {
00603                 delta = (pos-prevStepPos);
00604                 rot = unitZ.cross(delta.unit());
00605                 a = asin(rot.mag());
00606                 rot = rot.unit();
00607                 // handle all 4 quadrants
00608                 b = unitZ.dot(delta.unit());
00609                 if(a >= 0.0) {
00610                         if(b >= 0.0)
00611                                 a = a;
00612                         else
00613                                 a = M_PI - a;
00614                 } else {
00615                         if(b >= 0.0)
00616                                 a = a;
00617                         else
00618                                 a = -M_PI + a;
00619                 }
00620                 p = 0;
00621                 if(a > tolerance)
00622                         p = new G4RotationMatrix(rot,a);
00623                 tmp = G4ThreeVector(0,0,-stepZ);
00624                 if(p)
00625                         tmp = *p * tmp;
00626                 tmp += stepPos;
00627 //printf("addStep prev interpolate x,y,z=%.3f,%.3f,%.3f  axis=%.3f,%.3f,%.3f aDeg=%.1f\n",stepPos.x(),stepPos.y(),stepPos.z(),rot[0],rot[1],rot[2],a/deg);
00628                 segmentRCVector[segmentRCVector.size()-2].interpolate
00629                                                 = BLCoordinateTransform(p,tmp);
00630         }
00631 
00632         // update after this segment
00633         prevStepPos = stepPos;
00634         stepPos = pos;
00635         stepZ = z;
00636 }


Member Data Documentation

Referenced by ReferenceCoordinates().

Referenced by addStep(), and PreUserTrackingAction().

Referenced by addStep(), and PreUserTrackingAction().

G4ThreeVector BLCoordinates::ReferenceCoordinates::unitZ [static, private]

Referenced by addStep().


The documentation for this class was generated from the following file:
g4beamline