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