1------------ 2ZOOM classes 3------------ 4 5Symbol pollution: 6It is undesirable to pollute the CLHEP namespace with the following symbols: 7DEGREES RADIANS ETA. So these are placed purely into the ZMpv namespace, 8which is defined in the SpaceVector.h backward-compatibility header. 9This has the consequence that ThreeVector.h is considerably simplified, 10since the plethora of constructors is greatly reduced. 11 12Spherical coordinate setting: 13Even though the direct spherical coordinate constructors are no longer in the 14main Hep3Vector class, the user can still use the set() methods in spherical 15coordinates. Except that again the keywords DERGREES RADIANS ETA are not 16available. Instead, we provide a few new methods, for example, 17 setRThetaPhi(double r, double theta, double phi); 18In these, alll angles are always treated as measured in RADIANS. 19 20Spherical coordinate setting mof V in LorentzVector: 21We again eliminate the keywords DEGREES RADIANS and ETA from the CLHEP class. 22THe same new methods are provided. This time, however, we feel no need to 23put the old methods in the PhysicsVectors class because nobody is using them. 24 25X_HAT Y_HAT Z_HAT: 26These were in the original physicsVectors package as UnitVectors. They remain 27so. Pure CLHEP users do have the Hep3Vectors HepXHat, HepYHat, HepZHat. 28Note, by the way, that X_HAT, Y_HAT, Z_HAT are static to each code unit that 29includes UnitVector.h. This is safer from the viewpoint of subtle 30order-of-initialization issues. Coders should not use HepXHat in 31initialization code that will execute prior to main() because it is not 32guaranteed that they will be initialized before they are used. 33 34 35-------------------- 36LorentzTransformation 37-------------------- 38 39set from (bx,by,bz): 40The merged classes have to contain a constructor from three boost components 41because CLHEP does. They must contain set taking a boost vector because 42ZOOM does. There need not, a priori, be 43LorentzRotation::set(double,double,Hepdouble) but we include that to 44be a bit orthogonal. 45 46transform (Rotation r): 47While CLHEP has a separate method for transform taking a HepRotation, this 48is not strictly needed since HepRotation is a Hep3RotationInterface which in 49turn is a Hep4RotationInterface. If you know the argument is 3x3 you could 50do 3x3 times 4x4 (in principle faster) and for transform, the original CLHEP 51would do this. On the other hand, for multiplication this "efficiency" was 52not done; there is no operator* (HepRotation). In reallity, the time needed 53for 3x3 times 4x4 is not significantly less, certainly not enough to warrant 54the additional complication. So we simple provide the transform method taking 55a 4 rotation interface, which will break no code. 56But for pure rotations around coordinate axes and boosts along axes, we do 57provide such methods as rotateZ and boostZ. Here the efficiency difference 58is marked. Besides, CLHEP has these explicitly. 59We also must keep the technically superfluous rotate(delta,axis) and 60boost(3 doubles or 3-vector) methods. 61 62Split of .cc files: 63Outside the main LorentzRotation.cc is 64LorentzRotationC.cc set(col1, col2, col3, col4) and related constructors 65LorentzRotationD.cc all the decompose methods 66 rectify 67 compare 68 distance2 (uses decompose) 69 70rotateX, Y and Z: 71Although these are inline in CLHEP, we make them normal now. The reason is 72that we can thus take advantage of rather big savings in algorithm (by 73utilizing the fact that the rotation only involves an X rotation or whatever). 74 75ZMxpv in LorentzRotation.cc 76As a reminder, the ZMthrow macro is defined as outputting its argument and 77aborting. (ZMthrowC does not abort). That said, should we use ZMthrow 78(defined in ZMxpv.h) in the basic LorentzRotation class? I think we have to: 79the method set (double, double, double) -- which was present in CLHEP -- had 80a flaw in that it would take sqrt of a negative number if the arguments 81supplied had mag2 > 1. We really should behave more sensibly here ahd ZMthrow 82is the best we can do. 83 84Physical coupling: 85Currently, BoostX needs LorentzRotation.h and so forth, because the product of 86a boost times an Hep4RotationInterface is a LorentzRotation. We could 87probably lessen this sort of coupling but maybe not without sacrificing 88speed. At any rate, I short-circuited design though on this issue in favor 89of getting the merge done! 90 91Efficiency of distance2 for boosts: 92We can, by providing distance2(HepLorentzRotation) and the other concrete 93classes, significantly speed up this computation, because we don't have to go 94back and forth through HepAxisAngle for the rotation decompositin and 95Hep3Vector for the boost. However, this would add another 15 methods to each 96header (assuming we would want these gains in isNear and HowNear also); 97I decided it might not be worth it. 98 99TODO: Test rotateX, Y, Z; boostX, Y, Z -- these are I think new. Just check 100 against the equivalent form by instantiating a general Lor. Rot 101 based on a ROtationX and so forth. 102 103 104 105-------- 106Rotation 107-------- 108 109Classes: 110ZOOM has the concepts of RotationX, RotationY, RotationZ, LorentzBoost, 111LorentzBoostX, LorentzBoostY, LorentzBoostZ. These are useful and will become 112part of CLHEP. THe boost classes may be in their own header file. 113 114Inheritance structure: 115I am telescoping a lot of thought into a few words here. 116ZOOM has RotationInterface and LorentzTransformationInterface, which 117provide those methods available for GETTING INFORMATION ABOUT generic 118Rotations and LorentzTransformations. We should keep these. The proper 119inheritance is that RI derives from LTI, because anything you wish to ask 120about a LT you could equally well ask about a R. From LTI, one derives 121LT, and each of the boosts. From RI, one derives Rotation and its special 122cases. We then can derive RotationX from Rotation, being careful to 123supply private throwing methods when attempting to do an illegal mutation. 124(Private so that the compiler will catch the error whenever possible; 125but implemented so that if a RotationX is passed to a routine expecting a 126Rotation &, and the user tries to change it in an illegal way, he won't 127get an invalid RotationX in a continuing program. 128 129 130Also, RotationAboutCoordinateAxis and BoostAlongCoordinateAxis are gone; 131they were not useful enought to be worth their complexity cost. 132 133Virtual destructor: 134Since the classes have to inherit from a virtual interface (to match ZOOM 135compatibility) they have Vtables anyway. For various technical reasons, 136the virtual mechanism is useful. By the way, UNLIKE the case for 3-vectors 137and 4-vectors, the overhead cost is small, and the number of distinct 138Rotation objects in our key jobs is not in the millions, so the virtual 139mechanism is not at all costly. 140 141Names of interface classes: 142Since CLHEP users will see these classes, and may well use them (as in the 143case of passing a generic interface for a Rotation and letting the code 144select the efficient operator() if it is specialized to an axial rotation), 145the names should be CHLEP-like. Thus Hep3RotationInterface and 146Hep4RotationInterface. As usual, the ZOOM names are placed in a separate 147header and will be namespace-guarded. 148 149Header file completeness: 150It is necessary (so that CLHEP users can continue to rely on the header for 151finding out what methods are available) that all the methods available for 152HepRotation appear in that class'es definition. No problem, since most 153are pure virtual in the base class anyway (and thus had to be present anyway.) 154There may be a few exceptions which we will have to be sure are present. 155 156tolerance sharing: 157It is right to use the same tolerance for RotationInterface that it gets by 158inheritance from LTI. This avoids some thorny dynamic-vs-static behavior 159differences. 160 161decompose method: 162There is a method (actually a pair of signatures) to decompose a LT into a 163pure rotation times a pure boost (and also boost times rotation). This does 164not really belong in the interface, even though it is a matter of getting 165information about a LT, and even though they can be defined for any sort 166of specialized LT. The reason is that the interface class should not need 167to know about two of its concrete descendants! Instead, decompose(R,B) will 168be a method of HepLorentzRotation (= LorentzTransformation). This is a subtle 169change from the ZOOM things but I think it VERY unlikely that anybody was 170doing decompose on an anonymous LorentzTransformationInterface &. 171Meanwhile, however, the compare() method really needs decompose! And 172if I take compare() out of the interface, then all the dictionary-ordering 173comparisons will need to be repeated in derived classes. Solution: There 174is an ADDITIONAL method decompose (Hep3Vector& boost, AxisAngle& rotation). 175The interface does know about these, so that is fine. And comparison is of 176course just as valid using these (in fact, that is how it was being done 177anyway). Now compare() becomes inline in the base class, and decompose 178is the virtual method it utilizes. 179 180Where should the RotationX header be: 181I will go with the obvious: RotationX.h etc. 182 183Operator() and [][]: 184ZOOM did not have these. Since these are not easy to implement with the same 185semantics as in CLHEP, for an arbitrary Hep3RotationInterface, and since they 186do not have to be there, we won't try to put them there. Similarly, they are 187absent from RotationX etc. Only HepRotation has these methods. 188 189Commonality in RotationX, RotationY, RotationZ: 190We repeat a lot of trival routines like xt() for these classes. Since they 191are identical it is tempting to factor them out, having RotationX etc inherit 192from RACA (RotationAboutCoordinateAxis). However, for code simplification 193and to avoid subtle using issues we have just eliminated that trick from 194PhysicsVectors. So we eat the extra code. 195 196inverseOf: 197This method, declared in the RotationInterface class as a friend, introduces 198bad coupling between the interface and Rotation (which the method returns). 199Instead, we put it into the concrete classes. 200 201PhiX, thetaX, etc for RotationX, RotationY, RotationZ: 202We could fairly easily avoid taking an atan2 or acos. For example, 203RotationX::thetaZ can just do return d. In some of the other cases you have 204to branch according to the qudrant of delta, but in no case do you need an 205inverse trig taken. However, for maximal safety, I just use the same 206code as was in CLHEP originally. The only mod made is that IN COMMENTS I 207put some faster implementations; later we can decide to use these but I 208believe the frequency of cuse of RotationX::phiX etc. will be negligible 209anyway. 210 211 212Equivalent methods: 213In principle you don't want to repeat code. So for example, the rotateX 214method could be implemented as *this= RotationX(delta)* *this. However, 215except for absolutely trivial cases, I feel it unacceptable to take any 216risk of existing CLHEP methods yielding different results (similarly for 217ZOOM methods that have no exact CLHEP match. So for instance I leave the 218implementatoin of getAngleAxis(double &, Hep3Vector &) even though it 219could be written as simply as 220 { HepAxisAngle z = axisAngle(); delta=a.delta; axis=a.axis; } 221(Given the split into several .cc files, the total code pulled in for a 222typical application will shrink, anyway.) 223Careful note will be made of all such "dual-implementation" situations, and 224we will take advantage by testing for equivalence in our test suites. 225 226Private data: 227ZOOM declares a rep3x3 struct which is very usreful for people who "just 228want the damn matrix." This is useful enough that we add it to CLHEP in 229RotationInterfaces.h . But also, the concrete class Rotation uses 230a Rep3x3 as its private data. In CLHEP the private data is just rxx, rxy 231... rzz. In the spirit of decided close things in favor of cooperation, we 232use the CLHEP form. 233 234To inline or not to inline: 235Several inline methods of HepRotation FAR exceed sensible standards for 236inlining. I have moved these to the .cc file: 237 operator==(), isIdentity(), 238 239operator>>: 240It might be nice to have an input method such that if you take the output 241of operator<< you get the original. However, that was not present in either 242ZOOM or CLHEP and I am not coding it at this time. 243 244HEP_SHORT_NAMES: 245It looks like if HEP_SHORT_NAMES is defined, then Rotation will collide with 246the ZOOM Rotation class. We will (for now) just say that you can't have both. 247We could do something fancier like have the ZOOM header check for and undef 248HEP_SHORT_NAMES when including the CLHEP Rotation.h but I will leave that for 249future consideration. 250 251 252Split into code units: 253Rotation.cc Original CLHEP Rotation, plus 254RotationIO.cc IO (just put() - why pull in iomanip.h if not needed 255RotationA.cc Axis-angle routines 256RotationE.cc Euler angle routines 257RotationC.cc Long routines involving rectifying near-rotations 258 (for example, constructor from 3 column vectors) 259RotationL.cc 3-Rotation routines involving 4-rotation arguments, 260 thus requiring linking 4-rotation code units. 261RotationP.cc All other methods originating in PhysicsVectors 262 263 264"Clash-table": 265 266operator * (v) I unified to return operator() (v). I use the CLHEP 267 implementation of (the equivalent) operator*(v) - but 268 as discussed, this is moved into the .cc, not .icc. 269 270operator == I left the CLHEP code for Rotation rather than using 271 the base class method which would return (compare(v)==0) 272 (which is a lot more work). 273 274getaxisAngle and getAngleAxis 275 276Multiplicatoin in Rotation Group: 277In principle one might like to have all Rotation*Rotation operations as free 278methods. However, the "double-dispatch" issue rears its ugly head, and the 279bottom line is that if we do it that way then we are forced to have ambiguous 280signatures. We instead provide multiplication as a member function. It 281can't be virtual in the base Hep3RotationInterface class, however, since it is 282"not good" for Hep3RotationInterface to have to know about Hep3Rotation. 283In short, we are using the simplest and least sophisticated way to implement 284these, so that things will compile everywhere. 285 286 287- - - 288 289operator() (LrentzVector) 290 291HepRotation (AxisAngle) and corresponding set() 292HepRotation (EulerAngles) and corresponding set() 293colX, colY, colZ, rowX, rowY, rowZ 294phi(), theta(), psi() 295axis(), delta() 296setPhi, setAxis, and so forth. 297setRows() 298compare, operator>, operator<, operator>=, operator<= 299distance2(), howNear(), isnNear() 300norm2() 301rectify() 302a static Rotation::IDENTITY 303methods treating the Rotation as a Hep4RotationInterface: 304 col1 ... col4; row1 ... row4 305 306- - - 307 308operator== etc inline: 309 310Since compare() will be virtual, all these comparison operators can be 311inline in the interface class. 312 313Inlining col1 etc: 314 315These should be inline, just like operator==, in the interface classes since 316everytihing is written in terms of xx(), xy()... which are virtual. However, 317in the individual spcialized classes we may profitably override these anyway. 318 319decompose: 320 321You don't want the interface class to know about its derived classes. 322So decompose(R,B) is not a good idea. A right way would be 323 324virtual void decomposeBR ( Hep4RotationInterface & b, 325 Hep4RotationInterface & r ) const = 0; 326virtual void decomposeRB ( Hep4RotationInterface & r, 327 Hep4RotationInterface & b ) const = 0; 328 329and the signatures of decompose invoving a Rotation and a boost appear 330in the concrete classes. 331 332But the decomposeRB and BR methods should NEVER be used since it does not 333pay to return a whold LT when a Rotation or boost is called for. Plus, 334you get a dangerous object: A LT with known extra properties. 335 336I eliminate decompose from the generic interface altogether -- decompose 337becomes purely a method of the concrete LorentzTransformation class. 338 339Forbenius: 340eliminate it. 341 342Things moved from CLHEP into RotationInterfaces: 343 344HepRotation_row: 345 346Is R[i][j] 1 or 0 based in CLHEP? NOte that for Hep3Vector, v[i] is 3470-based. So I can surely use the trick of returning a Hep3Vector as a row. 348I should try it, but I would think I can eliminate class HepRotation_row 349and have inline const Hep3Vector operator [] (int) const; because 350a = r[i][j] would then have the same behavior -- and because nobody is 351using things like HepRotation HepRotation_row myrow; myrow = ... in real 352code. 353 354We must be careful, however: the return type of operator[] should not 355be Hep3Vector, because in the Hep4RotationINterface, the same reasoning says 356it should be a HepLorentzVector!!, And at that point the 0-based choice 357comes back to bite us: X,Y,Z,T = 0,1,2,3 seems very unnatural. Nonetheless, 358that is indeed the choice made in CLHEP (see LorentzVector.h where 359enum { X=0, Y=1, Z=2, T=3, NUM_COORDINATES=4, SIZE=NUM_COORDINATES }; 360 361If we do return a HepLorentzVector, how does the behavior change? 362All the correct suages, e.g. r[2][2], are still correct and unchanged. 363And if one does r[3][2] that does not have to change at all: operator[] 364on a HepRotation can point out an error if the argument is > 2. However, 365if somebody does r[2][3] that will come back 0 without an error, since 366it is perfectly acceptable to take w[3] where w is a HepLorentzVector. 367 368So either I should have a HepRot_row helper (as CLHEP does) or I must live 369with that non-catch. By the way, if a helper, it can be shared between 370classes, but what is the best way to do that... 371 372private data: 373ZOOM uses a Rep3x3 rep_; we go with the CLHEP data instead. 374 375setRows: 376Rather than replicate all that code, I will use setCOls and then invert! 377 378R.compare (Hep4RotationInterface & lt ): 379This is very awkward because we don't wish to pull in all of the LT stuff. 380But note that Rotation in ZOOM does NOT have these. SO we can drop them 381altogether. 382 383 384 385 386 387 388----------- 389PlaneVector 390----------- 391 392New methods when placing in CLHEP: 393These are inserted just for similarity with the other Vector classes... 394 Operator[] 395 L-value operator() and [] 396 isParallel, isOrthogonal, howParallel, howOrthogonal 397 compare, operator < > <= >= 398 setPolar 399 400Physical Coupling to Hep3Vector: 401We forward declare Hep3Vector, and any methods involving Hep3Vector are 402implemented in the .cc file, so a user using Hep2Vector need not pull in 403Hep3Vector.h. 404 405CMATH_NAMESPACE:: 406This is liberally used to prepare for ISOcxx portability, which handles all 407the of places where things like sqrt are found. CLHEP has its own congfigure 408mechanism, and till ISOcxx is in place, it is best to just remove this 409accomodation. (Later we may want to put it back in when ISOcxx is there. 410At that point, the whole package, includeing the old CLHEP implementations, 411should do have this change.) 412 413 414--------- 415UnitVector 416---------- 417 418Where does the UnitVector code go: 419Main issue is the fact that though this is not in CLHEP, we will not end up 420having a library in PhysicsVectors. Fortunately, we can mkae UnitVector.h 421completely self-contained: Every routine is either trivial or casts (*this) 422to a Hep3Vector and uses the implementation for that. So the UnitVector 423class leads to no library code of its own! 424 425C-style or modern casts: 426We have gone with old C-style casts for the purposes of using the Hep3Vector 427implementations. And to avoid any chance of a compiler actually copying 428the object (after all, we do have operator Hep3Vector()), we cast this as 429a Hep3vector* and use ->. Thus: 430 double phi() const {return ((Hep3Vector*)this)->phi();} 431We could instead have used a static_cast <Hep3Vector*> but that is really 432not any safer for us, and adds some risk of the some compilers not having 433that syntax, or of some compiler using our cast operator to create a temporary 434copy, which we don't want. 435 436Name of UnitVector class: 437Since UnitVector is not in CLHEP (for now) we could just retain the name 438UnitVector. However, it may eventually become part of CLHEP, so I chose 439to parallel the situation for SpaceVector w.r.t. Hep3Vector. Thus, the header 440defines HepUnit3Vector in the global namespace, and inside the potential 441zmpv namespace typedefes UnitVector to be that. 442 443UnitVector as an argument: 444The conversion operator to Hep3Vector makes it trivial to use UnitVector as 445an argument to any routine that takes a Hep3Vector. 446There will be cases where it would be beneficial to have a special method 447taking advantage of the knowledge that a UnitVector need not be normalized. 448For the present, we will not attempt to obtain this advantage. In most cases 449the UnitVector is originally based on a Hep3Vector; there, the work of 450normalizing the vector twice can easily be avoided. 451 452rotationOf global methods: 453Since there is a conversion operator from UnitVector to Hep3Vector, 454we could have omitted the global rotationOf(UnitVector, ...) methods. 455But because when such a method is applied the answer is known to be a 456UnitVector, we chose to provide methods with those signatures, returning 457HepUnit3Vector instead of Hep3Vector. These simply treat the UnitVector 458as a Hep3Vector, perform the rotation, and return the result as a unit 459vector. 460 461 462 463-------------- 464LorentzVector 465-------------- 466 467** Et 468** Et is E Pperp/p. 469 470** Metric selector: 471** ZOOM allows the user to set metric as TimePositive or TimeNegative; 472** the default is TimePositive. CLHEP always does TimePositive. The 473** cost of the flexibility is small: Roughly 10% in dot, diff2, and mag2 474** and no other routines altered. Because of this, I am keeping metric 475** flexibility in the package. 476 477** XYZT or TXYZ in constructor: 478** ZOOM prevented ambguity by having a type Tcomponent. The quote from 479** the .h file is "We do not support forming a LorentzVector from 4 480** undistiguished Scalars, which could lead to uncaught mistakes of 481** putting t first. CLHEP chose to provide this ordinary 4-doubles 482** signature, with T assumed to be last. We of course must keep all 483** three. The possibility of user error does exist but was already 484** there in CLHEP and nobody was getting burnt. 485 486** "explicit" keyword: 487** ZOOM allows constcuting a LorentzVector from just p (with e = 0) 488** and from just e (with p=0). ZOOM uses the "explicit" keyword to 489** protect against possible mishaps with such consturcutions. Since 490** CLHEP already uses the "explicit" keyword (in the Matrix package) 491** we will retain it here. 492 493** mag2() and m2(): 494** CLHEP treats mag2() as the same as restMass2(). This is the only possible 495** meaning when the metric is fixed as ---+. However, if there is flexibility 496** in the sense of the metric, it is most natural to consider mag2() to be 497** defined as w.dot(w). This is how ZOOM treats it. Since CLHEP users will 498** not have altered the choice of metric, they will not be affected if the 499** ZOOM definition is used, so we go that way. On the other hand, m2() really 500** sounds like it should mean the physics mass squared; what we call in ZOOM 501** restMass2(). ZOOM does not have a method m2(). So we leave m2 as metric 502** independant, and identical to restMass2(). 503 504** boostVector: 505** In CLHEP there is no checking, either for 0 or for tachyonic 506** case. In ZOOM there is checking, which takes very little time. 507** I think the zoom routine is therefore better, even though it is no longer 508** appropriate to inline it. 509 CHANGELOG 510 511** Rotation methods: 512** Again we should separate methods that force the load of the Rotation class. 513** For practical purposes, that implies that methods like rotate() are no 514** longer inline, and that as in the ThreeVector class we separate the .cc 515** files. Also, again we have the rotation methods returning 516** HepLorentzVector& rather than void, so things can be chained. 517 518** Boost methods: 519** We have the rotation methods returning HepLorentzVector& rather than void, 520** so things can be chained. Also, we feel the boost methods along an axis, 521** boostZ in particular, reall ought to be in the main part of the header. 522** ZOOM does several checks to see that the bosot vector is not tachyonic. 523** Here, we will forego these and use the CLHEP implementations. 524 525** Methods acting on containers of LorentzVectors: 526** This is present in ZOOM, for example, 527** list<LorentzVector> s; double m = s.invariantMass(); 528** At least for now, we will omit this, so as not to introduce template 529** complications into CLHEP. If necessary, we can put this back in the 530** LorentzVector.h file in the ZOOM area that typedefs LorentzVector from 531** HepLorentzVector. 532 533** Physical design to avoid unnecessary loading of Rotation modules: 534** As per the Hep3Vector class, we split off almost all the implementations 535** of the new ZOOM features so a "pure" CLHEP user gets no more code loaded 536** that previously. And as in that case, we split the ZOOM implementations 537** among several .cc files. Also, we split out the implementations of features 538** originally in CLHEP which would "drag in" Rotation.cc, and which would 539** force loading of LorentzRotation.cc. Thus the implementation files are: 540** LorentzVector.cc original CLHEP 541** LorentzVectorR.cc methods possibly involving HepRotation 542** LorentzVectorL.cc original CLHEP involving HepLorentzRotation 543** LorentzVectorC.cc comparison operations from ZOOM 544** LorentzVectorK.cc relativistic kinematics from ZOOM 545** LorentzVectorB.cc boosts and rotations from ZOOM, not involving 546** HepRotation or HepLorentzRotation 547 548** Unit axial 4-vectors: 549** We provide X_HAT4, Y_HAT4, Z_HAT4, T_HAT4 as statics, in the header. 550** We use the inline constructor in original CLHEP to avoid the need to pull 551** in additional code. 552 553- - - 554 555inline HepLorentzVector(double, const Hep3Vector &); 556 557operator /= (Hepdouble c) 558operator / (const LorentzVector & v, Hepdouble c) 559 560inline bool isSpacelike() const; 561inline bool isTimelike() const; 562inline bool isLightlike(Scalar epsilon=tolerance) const; 563 564 565- - - 566 567 568------------ 569SpaceVector 570------------ 571 572** Namespace: 573** Hep3Vector is not enclosed in a namespace. SpaceVector is; but most of our 574** users currently disable namespaces at this point. I enclose the typedef 575** defining SpaceVector in namespace zmpv, and leave Hep3Vector bare. I would 576** like to use that as the pattern: Any new concept is placed in zmpv, all 577** existing ones remain in ::. That would be awkward, for example 578** ZMpvDEGREES_t is used directly now in Hep3Vector. But I do go the 579** necessary distance: Possibly conflicting symbols such as DEGREES are put 580** in the zmpv namespace. 581 582 Needs further correction: See "ZOOM classes" above. 583 584** R, rho confusion: 585** CLHEP, --IN COMMENTS ONLY-- refers to the radius in spherical 586** coordinates as rho, and the distance from the Z axis in 587** cylindrical coordinates as R. ZOOM uses the oppopsite names, and 588** in fact uses these names in method names. I have altered the CLHEP 589** comments to make the nomenclature consistent; the meanings are still 590** clear from the comments. For example: 591 inline double perp() const; 592 // The transverse component (R in cylindrical coordinate system). 593 CHANGELOG 594 595** Use of UnitVector: 596** At first, I thought that we should keep UnitVector for its efficiency 597** benefits. On further inspection, I noticed that these benefits are 598** small, and that having UnitVector inherit from SpaceVector (with non- 599** virtual methods) is unwise. So I will eliminate UnitVector, which 600** has the benefit of reducing interface bloat as well. If any Fermilab 601** users rely on UnitVector, I may have to add a UnitVector class; but 602** Hep3Vector (and HepRotation) will not rely on UnitVector. 603 604** The name angle and theta: 605** These are synonmous. So why not drop one? Well, even if I said let's 606** use the CLHEP form, CLHEP has theta for angle wrt z axis, and angle for 607** angle wrt an arbitrary direction. 608 609** Use of AxisAngle and EulerAngles: 610** These class are very useful and simple structures for holding the result 611** of a nice intuituve decomposition of a rotation: Axis, and how far to 612** rotate, or the three EUler angles. They are worth retaining. 613 614** EulerAngles conventions: 615** ZOOM Rotations know about EulerAngles. CLHEP does not. We are faced with 616** some options: (1) set up a static variable to indicate choice of EA 617** convention -- HORRIBLE. (2) Change to some other convention and strand 618** any existing ZOOM users -- Unacceptable. (3) Leave things the way they 619** are, and later we can provide conversion routines to go to other EA 620** conventions. (3) looks right. Later, we could define HepAeroEAs for 621** example, with conversion constructors to/from HepEulerAngles. 622 623** Hep3Vector knows about HepRotation: 624** In PhysicsVectors, there is a heirarchy in which vectors do not know about 625** rotations. The methods transform(const HepRotation &) and 626** *=(const HepRotation &) break this heirarchy. Thus ANY CLHEP PROGRAM 627** THAT USES Hep3Vector MUST LINK IN hepRotation!! This is not desirable. 628** I shouldn't "fix" this by eliminating transform from CLHEP. Instead I 629** will break apart ThreeVector.cc, putting the Rotation methods in their 630** own little file. ThreeVectorR.cc If the user uses Hep3Vectors but not 631** rotations, he then won't pull everything in. 632 CHANGELOG 633 634** Hep3Vector::rotate signatures: 635** For equivalent rotate() methods, ZOOM takes (axis, delta) where 636** CLHEP takes (delta, axis). THere is no harm in leaving this alone. 637 638** Return types for rotateX, rotateY, rotateZ (void in CLHEP) 639** CLHEP and PhysicsVectors each have these three methods, and they are 640** identical except that the ZOOM version returns a reference to *this. 641** This is convenient for certain chained operations, and costs nothing; 642** I don't wish to break ZOOM user code for zero reason, so I have made 643** the CLHEP method conform to this convention. There are a couple of other 644** methods, rotate and rotateUz, whith the same void return type but since 645** these methods or signatures don't appear in the original ZOOM classes, 646** I leave the return type alone. 647 648** Hep3Vector::rotate inefficient: 649** CLHEP has implemented a rotate() method on a 3-vector in a very 650** inefficent way, first forming an identity Rotation, then rotating that 651** by axis and angle (in itself quite a task) then douing vector *= rotation. 652** For now, I leave this alone -- people are of course free to use the ZOOM 653** signature axis, delta which I believe will be much faster. The speed 654** advantage of the ZOOM routines is decreased a bit because we no longer 655** provide the form where axis is a known UnitVector. 656 657** Additional methods and physical coupling: 658** Were we to merely put all the new SpaceVector methods into ThreeVector.h, 659** then anybody using the class would pull in all that additional code. 660** instead, we break the implementations up into several new files: 661** The polar/azimuthal decomposition methods SpaceVectorD.cc 662** All new methods involving rotation SpaceVectorR.cc 663** Other new intrinsic and relative properties SpaceVectorP.cc 664** All other new methods (constructors, nearness, ...) SpaceVector.cc 665 666** operator *= with a Rotation: 667** Another case where ZOOM decided it was too ambiguous, and CLHEP has 668** just decided which way to read it. Here, things are not that bad: 669** C++ semantics leads you to expect v = M*v and that is what is done. OK. 670 OOPS, NOT OK. C++ semantics leads you to expect v = v*M but the 671 code does v = M*v (which is what physics would lead you to expect!! 672 673 674** ZMthrow: 675** PhsyicsVectors is set up for use of the Exceptions package. Though we 676** are directed not to use it wuite yet, I am not giving up on it eventually 677** being in use; it has advantages. For now, I leave the ZMthrows in, but 678** substitute for ZMthrow.h and ZMxpv.h macros which turn these into cerr<< 679** lines like the others in Vector. Also, I introduce a macro ZMthrowC which 680** I use wherever it seems exiting is too strong an action after reporting 681** the problem, and a sensible Continuation is possible. Once Exceptions 682** are incorporated into Vector (if ever) ZMthrowC may eventually be #defined 683** as ZMthrow since the Exceptions mechanism can do the ignoring for us. 684 685** Ambiguous angles: 686** CLHEP often, when faced with an ambiguous angle such as the cosing of the 687** angle between vector v and a zero vector, simply returns 1. ZOOM had 688** issued a ZMthrow, and returns 1. This was OK because a user could set 689** up to ignore the ZMthorw. We can live with the CLHEP choice on those 690** routines already in CLHEP. For some that are not originally in CLHEP, 691** such as cos2Theta, we leave the ZOOM behavior intact. 692 693** SetTheta inline: 694** I disagree with setTheta and setMag() etc. being inline (too much logic) 695** but I won't press the issue. 696 697** Names of AxisAngle and EulerAngles 698** Should I change these to HepAxisAngle etc? I have decided to do so: 699** the names are unique enough that I am not too worried about clashes, 700** but I would have trouble getting the namespace placement right if 701** there were no version in the global namespace. The AxisAngle and 702** EulerAngles classes are also placed in the zmpv namespace. 703 704 705- - - 706 707 708Items added to the "main" part of the interface (above the esoteric area): 709 710set (x,y,x): Moved into main part. 711 CHANGELOG 712 713setEta, setCylTheta, setCylEta: NO synonyms; I put these up into main part. 714 CHANGELOG 715 716operator / (double) : Added to main part. 717 CHANGELOG 718 719operator /= : Added to main part. 720 CHANGELOG 721 722isNear: I have put isNear in the main section, because it is quite useful 723 at least to our users. I use the simplest and quickest forms for 724 isNear and all related routines; contortions to account for the 725 possibility of components being greater than 10**75 are silly. 726 Similarly, I put HowNear and DeltaR into the main section. 727 CHANGELOG 728 729cos2Theta: against the z axis, placed in main part next to cosTheta(). 730 CHANGELOG 731 732 733et2, et: I have included transverse energy/ 734 735- - - 736 737 738Polar constructors: We add the 8 varieties of polar and cylindrical 739 constructors. We keep the microtypes.h file to be able to 740 distinguish these. 741 742getX getY getZ: Synonyms. 743 744getR: Synonym for mag. Inline in CLHEP, and we go that way too. 745 746getTheta getPhi: not quite Synonnyms: CLHEP Checks for invalid cases in 747 a different way. However, behavior of atan2 is adequate for CLHEP 748 check to be OK. Therefore make synonymous. 749 750getRho(), rho: Synonym for perp() 751 752getEta, eta: Synonym for pseuoRapidity. 753 754setR: Synonym for setMag(). I disagree with setR, setTHeta, etc being 755 inline, but I won't press the issue. 756 757Triple setters: Put among the new constructors. 758 759setCyl and setCyl using Eta: Put into the esoteric constructors area even 760 though no constructor corresponds to these. 761 762operator+, -, scalar *: These are done as non-friends, in the .icc file, 763 utilizing the inline access methods. That is fine, except it would 764 be nice to be able to see them when looking at the header. I 765 would add those declarations, but because of the HEP_DEBUG_INLINE 766 complication that is awkward, and less necessary. 767 768operator scalar /: Not present; I will add to the header, as a non-inline 769 only. 770 771compare, operator>, etc: Added to esoteric section 772 773howNear, deltaR, get and set tolerance: added to Esoteric section. 774 I have put isNear in the main section, because it is quite useful 775 at least to our users. 776 777isParallell, howOrthogonal, etc.: added to Esoteric section. 778 779v1*v2: ZOOM decided this was too ambiguous. However, given that CLHEP 780 mad a choice, we can embrace that choice. CLHEP already has 781 v1.dot(v2) so we need not add that synonym. 782 783beta: Synonym for mag. 784 785gamma, collinearRapidity: 786rapidity: Put these into the section with reference direction. 787 788angle: Synonym for theta() in the z form. angle(v) is already present 789 in main part. So is theta(). SpaceVector and UnitVector are 790 separate in principle, bit for angle(u) the improvement in speed 791 iss too small to be worth it, so we eliminate the Unit signature. 792 793cosTheta: against the z axis, already present in main part. 794 795cos2Theta: against the z axis, placed in main part. 796 797project, perp, perpPart: Missing ones are in esoteric. 798 The following already had 3-vector forms in CLHEP: 799 perp(v) perp2(v) 800 801polar decompostion: In the form relative to a reference direction, since the 802 direction is now supplied as a 3-vector (not a UnitVector) we needed 803 to modify that code. 804 805 TODO: Modify decomposition code. 806 807rotationOf and related friends: These need not be friends. Nor, 808 given the time taken to rotate, need they be inline. Move to 809 global methods section. 810 811How do I get PI? 812 I use CLHEP::pi which is available in CLHEP/Units/PhysicalConstants.h 813 814X_HAT, Y_HAT, Z_HAT: 815 put as static const Hep3Vector in the .h file. 816 817 818 819 820TODO: Rotation 821TODO: LorentzTransformation 822 823 824