00001
00002
00003
00004
00005
00014 #ifndef __TOPTOOLSTOPOLOGYWORKER__
00015 #define __TOPTOOLSTOPOLOGYWORKER__
00016
00017 #warning The TopologyWorker class is currently not supported anymore! There might be issues in its implementation.
00018 #warning If you are still using it or planned to do so, please contact the admins of the corresponding CMSSW package.
00019 #warning You can find their e-mail adresses in: cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/TopQuarkAnalysis/TopTools/.admin/
00020
00021 #include "TF1.h"
00022 #include "TMath.h"
00023 #include "TClass.h"
00024 #include "TString.h"
00025 #include "TRandom.h"
00026 #include "TMatrixD.h"
00027 #include "TLorentzVector.h"
00028
00029 #include <cmath>
00030 #include <iostream>
00031
00032 class TopologyWorker
00033 {
00034 public:
00035 TopologyWorker(){;}
00036 TopologyWorker(bool boost);
00037 virtual ~TopologyWorker(){;}
00038
00039 void clear(void){m_np=0;m_np2=0;return;}
00040
00041 void setPartList(TObjArray* e1, TObjArray* e2);
00042 void setVerbose(bool loud){m_verbose=loud; return;}
00043
00044 void setThMomPower(double tp);
00045 double getThMomPower();
00046 void setFast(int nf);
00047 int getFast();
00048
00049 TVector3 thrustAxis();
00050 TVector3 majorAxis();
00051 TVector3 minorAxis();
00052
00053 TVector3 thrust();
00054
00055
00056 double oblateness();
00057 double get_sphericity();
00058 double get_aplanarity();
00059 double get_h10();
00060 double get_h20();
00061 double get_h30();
00062 double get_h40();
00063 double get_h50();
00064 double get_h60();
00065
00066
00067 void planes_sphe(double& pnorm,double& p2, double& p3);
00068 void planes_sphe_wei(double& pnorm,double& p2, double& p3);
00069 void planes_thrust(double& pnorm,double& p2, double& p3);
00070 void sumangles(float& sdeta, float& sdr);
00071
00072 double get_ht() {return m_ht;}
00073 double get_ht3() {return m_ht3;}
00074 double get_et0() {return m_et0;}
00075 double get_sqrts() {return m_sqrts;}
00076 double get_njetW() {return m_njetsweighed;}
00077 double get_et56() {return m_et56;}
00078 double get_centrality() { return m_centrality;}
00079
00080 private:
00081 bool m_verbose;
00082 void getetaphi(double px, double py, double pz, double& eta, double& phi);
00083 double ulAngle(double x, double y);
00084 double sign(double a, double b);
00085 void ludbrb(TMatrix *mom,
00086 double the,
00087 double phi,
00088 double bx,
00089 double by,
00090 double bz);
00091
00092 int iPow(int man, int exp);
00093
00094 double m_dSphMomPower;
00095
00096
00097 double m_dDeltaThPower;
00098
00099
00100 int m_iFast;
00101
00102
00103 double m_dConv;
00104
00105
00106 int m_iGood;
00107
00108
00109
00110 TMatrix m_dAxes;
00111
00112
00113
00114
00115
00116 TVector3 m_ThrustAxis;
00117 TVector3 m_MajorAxis;
00118 TVector3 m_MinorAxis;
00119 TVector3 m_Thrust;
00120
00121 TRandom m_random;
00122
00123 TMatrix m_mom;
00124 TMatrix m_mom2;
00125
00126 double m_dThrust[4];
00127 double m_dOblateness;
00128 int m_np;
00129 int m_np2;
00130 bool m_sanda_called;
00131 bool m_fowo_called;
00132 bool m_boost;
00133 bool m_sumangles_called;
00134 double m_sph;
00135 double m_apl;
00136 double m_h10;
00137 double m_h20;
00138 double m_h30;
00139 double m_h40;
00140 double m_h50;
00141 double m_h60;
00142 double m_ht;
00143 double m_ht3;
00144 double m_et0;
00145 double m_sqrts;
00146 double m_njetsweighed;
00147 double m_et56;
00148 double m_centrality;
00149
00150 void sanda();
00151 void fowo();
00152 static int m_maxpart;
00153
00154 void CalcWmul();
00155 void CalcSqrts();
00156 void CalcHTstuff();
00157 double CalcPt(int i) { return sqrt(pow(m_mom(i,1),2)+pow(m_mom(i,2),2));}
00158 double CalcPt2(int i) { return sqrt(pow(m_mom2(i,1),2)+pow(m_mom2(i,2),2));}
00159 double CalcEta(int i) {double eta, phi;getetaphi(m_mom(i,1),m_mom(i,2),m_mom(i,3),eta,phi); return eta;}
00160 double CalcEta2(int i) {double eta, phi; getetaphi(m_mom2(i,1),m_mom2(i,2),m_mom2(i,3),eta,phi); return eta;}
00161
00162 };
00163
00164 class LessThan {
00165 public :
00166
00167 bool operator () (const TLorentzVector & tl1, const TLorentzVector &
00168 tl2)
00169 const {
00170 return tl2.Pt() < tl1.Pt();
00171 }
00172 };
00173
00174 Int_t TopologyWorker::m_maxpart = 1000;
00175
00176 TopologyWorker::TopologyWorker(bool boost):
00177 m_dSphMomPower(2.0),m_dDeltaThPower(0),
00178 m_iFast(4),m_dConv(0.0001),m_iGood(2)
00179 {
00180 m_dAxes.ResizeTo(4,4);
00181 m_mom.ResizeTo(m_maxpart,6);
00182 m_mom2.ResizeTo(m_maxpart,6);
00183 m_np=-1;
00184 m_np2=-1;
00185 m_sanda_called=false;
00186 m_fowo_called=false;
00187 m_sumangles_called=false;
00188 m_verbose=false;
00189 m_boost=boost;
00190 m_sph=-1;
00191 m_apl=-1;
00192 m_h10=-1;
00193 m_h20=-1;
00194 m_h30=-1;
00195 m_h40=-1;
00196 m_sqrts=0;
00197 m_ht=0;
00198 m_ht3=0;
00199 m_et56=0;
00200 m_njetsweighed=0;
00201 m_et0=0;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211 void TopologyWorker::setPartList(TObjArray* e1, TObjArray* e2)
00212 {
00213
00214
00215
00216 TMatrix mom(m_maxpart,6);
00217 TMatrix mom2(m_maxpart,6);
00218 double tmax = 0;
00219 double phi = 0.;
00220 double the = 0.;
00221 double sgn;
00222 TMatrix fast(m_iFast + 1,6);
00223 TMatrix work(11,6);
00224 double tdi[4] = {0.,0.,0.,0.};
00225 double tds;
00226 double tpr[4] = {0.,0.,0.,0.};
00227 double thp;
00228 double thps;
00229 double pxtot=0;
00230 double pytot=0;
00231 double pztot=0;
00232 double etot=0;
00233
00234 TMatrix temp(3,5);
00235 Int_t np = 0;
00236 Int_t numElements = e1->GetEntries();
00237 Int_t numElements2 = e2->GetEntries();
00238
00239
00240
00241
00242
00243 m_np=0;
00244 for(Int_t elem=0;elem<numElements;elem++) {
00245 if(m_verbose){
00246 std::cout << "looping over array, element " << elem << std::endl;
00247 }
00248 TObject* o = (TObject*) e1->At(elem);
00249 if(m_verbose){
00250 std::cerr << "TopologyWorker:SetPartList(): adding jet " << elem << "." << std::endl;
00251 }
00252 if (np >= m_maxpart) {
00253 printf("Too many particles input to TopologyWorker");
00254 return;
00255 }
00256 if(m_verbose){
00257 std::cout << "getting name of object..." << std::endl;
00258 }
00259 TString nam(o->IsA()->GetName());
00260 if(m_verbose){
00261 std::cout << "TopologyWorker::setPartList(): object is of type " << nam << std::endl;
00262 }
00263 if (nam.Contains("TVector3")) {
00264 TVector3 v(((TVector3 *) o)->X(),
00265 ((TVector3 *) o)->Y(),
00266 ((TVector3 *) o)->Z());
00267 mom(np,1) = v.X();
00268 mom(np,2) = v.Y();
00269 mom(np,3) = v.Z();
00270 mom(np,4) = v.Mag();
00271 }
00272 else if (nam.Contains("TLorentzVector")) {
00273 TVector3 v(((TLorentzVector *) o)->X(),
00274 ((TLorentzVector *) o)->Y(),
00275 ((TLorentzVector *) o)->Z());
00276 mom(np,1) = v.X();
00277 mom(np,2) = v.Y();
00278 mom(np,3) = v.Z();
00279 mom(np,4) = ((TLorentzVector *) o)->T();
00280 }
00281 else {
00282 printf("TopologyWorker::setEvent input is not a TVector3 or a TLorentzVector\n");
00283 continue;
00284 }
00285
00286
00287 if ( TMath::Abs( m_dDeltaThPower ) <= 0.001 ) {
00288 mom(np,5) = 1.0;
00289 }
00290 else {
00291 mom(np,5) = TMath::Power(mom(np,4),m_dDeltaThPower);
00292 }
00293 tmax = tmax + mom(np,4)*mom(np,5);
00294 pxtot+=mom(np,1);
00295 pytot+=mom(np,2);
00296 pztot+=mom(np,3);
00297 etot+=mom(np,4);
00298 np++;
00299 m_np=np;
00300 }
00301 Int_t np2=0;
00302
00303 for(Int_t elem=0;elem<numElements2;elem++) {
00304
00305 TObject* o = (TObject*) e2->At(elem);
00306 if (np2 >= m_maxpart) {
00307 printf("Too many particles input to TopologyWorker");
00308 return;
00309 }
00310
00311 TString nam(o->IsA()->GetName());
00312 if (nam.Contains("TVector3")) {
00313 TVector3 v(((TVector3 *) o)->X(),
00314 ((TVector3 *) o)->Y(),
00315 ((TVector3 *) o)->Z());
00316 mom2(np2,1) = v.X();
00317 mom2(np2,2) = v.Y();
00318 mom2(np2,3) = v.Z();
00319 mom2(np2,4) = v.Mag();
00320 }
00321 else if (nam.Contains("TLorentzVector")) {
00322 TVector3 v(((TLorentzVector *) o)->X(),
00323 ((TLorentzVector *) o)->Y(),
00324 ((TLorentzVector *) o)->Z());
00325 mom2(np2,1) = v.X();
00326 mom2(np2,2) = v.Y();
00327 mom2(np2,3) = v.Z();
00328 mom2(np2,4) = ((TLorentzVector *) o)->T();
00329
00330 }
00331 else {
00332 printf("TopologyWorker::setEvent Second vector input is not a TVector3 or a TLorentzVector\n");
00333 continue;
00334 }
00335 np2++;
00336 m_np2=np2;
00337 }
00338 m_mom2=mom2;
00339
00340 if (m_boost && m_np>1) {
00341 printf("TopologyWorker::setEvent Only boosting first vector so watch out when you do this!!!");
00342 TVector3 booze(-pxtot/etot,-pytot/etot,-pztot/etot);
00343 TLorentzVector l1;
00344 for (int k=0; k<m_np ; k++) {
00345 l1.SetPx(mom(k,1));
00346 l1.SetPy(mom(k,2));
00347 l1.SetPz(mom(k,3));
00348 l1.SetE(mom(k,4));
00349 l1.Boost(booze);
00350 mom(k,1)=l1.Px();
00351 mom(k,2)=l1.Py();
00352 mom(k,3)=l1.Pz();
00353 mom(k,4)=l1.E();
00354 }
00355 }
00356
00357 m_sanda_called=false;
00358 m_fowo_called=false;
00359 for (int ip=0;ip<m_maxpart;ip++) {
00360 for (int id=0;id<6;id++) {
00361 m_mom(ip,id)=mom(ip,id);
00362 }
00363 }
00364
00365 if ( np < 2 ) {
00366 m_dThrust[1] = -1.0;
00367 m_dOblateness = -1.0;
00368 return;
00369 }
00370
00371
00372 for ( Int_t pass=1; pass < 3; pass++) {
00373 if ( pass == 2 ) {
00374 phi = ulAngle(m_dAxes(1,1), m_dAxes(1,2));
00375 ludbrb( &mom, 0, -phi, 0., 0., 0. );
00376 for ( Int_t i = 0; i < 3; i++ ) {
00377 for ( Int_t j = 1; j < 4; j++ ) {
00378 temp(i,j) = m_dAxes(i+1,j);
00379 }
00380 temp(i,4) = 0;
00381 }
00382 ludbrb(&temp,0.,-phi,0.,0.,0.);
00383 for ( Int_t ib = 0; ib < 3; ib++ ) {
00384 for ( Int_t j = 1; j < 4; j++ ) {
00385 m_dAxes(ib+1,j) = temp(ib,j);
00386 }
00387 }
00388 the = ulAngle( m_dAxes(1,3), m_dAxes(1,1) );
00389 ludbrb( &mom, -the, 0., 0., 0., 0. );
00390 for ( Int_t ic = 0; ic < 3; ic++ ) {
00391 for ( Int_t j = 1; j < 4; j++ ) {
00392 temp(ic,j) = m_dAxes(ic+1,j);
00393 }
00394 temp(ic,4) = 0;
00395 }
00396 ludbrb(&temp,-the,0.,0.,0.,0.);
00397 for ( Int_t id = 0; id < 3; id++ ) {
00398 for ( Int_t j = 1; j < 4; j++ ) {
00399 m_dAxes(id+1,j) = temp(id,j);
00400 }
00401 }
00402 }
00403 for ( Int_t ifas = 0; ifas < m_iFast + 1 ; ifas++ ) {
00404 fast(ifas,4) = 0.;
00405 }
00406
00407
00408
00409 for ( Int_t i = 0; i < np; i++ ) {
00410 if ( pass == 2 ) {
00411 mom(i,4) = TMath::Sqrt( mom(i,1)*mom(i,1)
00412 + mom(i,2)*mom(i,2) );
00413 }
00414 for ( Int_t ifas = m_iFast - 1; ifas > -1; ifas-- ) {
00415 if ( mom(i,4) > fast(ifas,4) ) {
00416 for ( Int_t j = 1; j < 6; j++ ) {
00417 fast(ifas+1,j) = fast(ifas,j);
00418 if ( ifas == 0 ) fast(ifas,j) = mom(i,j);
00419 }
00420 }
00421 else {
00422 for ( Int_t j = 1; j < 6; j++ ) {
00423 fast(ifas+1,j) = mom(i,j);
00424 }
00425 break;
00426 }
00427 }
00428 }
00429
00430 for ( Int_t ie = 0; ie < work.GetNrows(); ie++ ) {
00431 work(ie,4) = 0.;
00432 }
00433 Int_t p = TMath::Min( m_iFast, np ) - 1;
00434
00435
00436 Int_t nc = iPow(2,p);
00437 for ( Int_t n = 0; n < nc; n++ ) {
00438 for ( Int_t j = 1; j < 4; j++ ) {
00439 tdi[j] = 0.;
00440 }
00441 for ( Int_t i = 0; i < TMath::Min(m_iFast,n); i++ ) {
00442 sgn = fast(i,5);
00443 if (iPow(2,(i+1))*((n+iPow(2,i))/iPow(2,(i+1))) >= i+1){
00444 sgn = -sgn;
00445 }
00446 for ( Int_t j = 1; j < 5-pass; j++ ) {
00447 tdi[j] = tdi[j] + sgn*fast(i,j);
00448 }
00449 }
00450 tds = tdi[1]*tdi[1] + tdi[2]*tdi[2] + tdi[3]*tdi[3];
00451 for ( Int_t iw = TMath::Min(n,9); iw > -1; iw--) {
00452 if( tds > work(iw,4) ) {
00453 for ( Int_t j = 1; j < 5; j++ ) {
00454 work(iw+1,j) = work(iw,j);
00455 if ( iw == 0 ) {
00456 if ( j < 4 ) {
00457 work(iw,j) = tdi[j];
00458 }
00459 else {
00460 work(iw,j) = tds;
00461 }
00462 }
00463 }
00464 }
00465 else {
00466 for ( Int_t j = 1; j < 4; j++ ) {
00467 work(iw+1,j) = tdi[j];
00468 }
00469 work(iw+1,4) = tds;
00470 }
00471 }
00472 }
00473
00474 m_dThrust[pass] = 0;
00475 thp = -99999.;
00476 Int_t nagree = 0;
00477 for ( Int_t iw = 0;
00478 iw < TMath::Min(nc,10) && nagree < m_iGood; iw++ ){
00479 thp = 0.;
00480 thps = -99999.;
00481 while ( thp > thps + m_dConv ) {
00482 thps = thp;
00483 for ( Int_t j = 1; j < 4; j++ ) {
00484 if ( thp <= 1E-10 ) {
00485 tdi[j] = work(iw,j);
00486 }
00487 else {
00488 tdi[j] = tpr[j];
00489 tpr[j] = 0;
00490 }
00491 }
00492 for ( Int_t i = 0; i < np; i++ ) {
00493 sgn = sign(mom(i,5),
00494 tdi[1]*mom(i,1) +
00495 tdi[2]*mom(i,2) +
00496 tdi[3]*mom(i,3));
00497 for ( Int_t j = 1; j < 5 - pass; j++ ){
00498 tpr[j] = tpr[j] + sgn*mom(i,j);
00499 }
00500 }
00501 thp = TMath::Sqrt(tpr[1]*tpr[1]
00502 + tpr[2]*tpr[2]
00503 + tpr[3]*tpr[3])/tmax;
00504 }
00505
00506
00507 if ( thp < m_dThrust[pass] - m_dConv ) {
00508 break;
00509 }
00510 if ( thp > m_dThrust[pass] + m_dConv ) {
00511 nagree = 0;
00512 sgn = iPow( -1, (Int_t)TMath::Nint(m_random.Rndm()) );
00513 for ( Int_t j = 1; j < 4; j++ ) {
00514 m_dAxes(pass,j) = sgn*tpr[j]/(tmax*thp);
00515 }
00516 m_dThrust[pass] = thp;
00517 }
00518 nagree = nagree + 1;
00519 }
00520 }
00521
00522 sgn = iPow( -1, (Int_t)TMath::Nint(m_random.Rndm()));
00523 m_dAxes(3,1) = -sgn*m_dAxes(2,2);
00524 m_dAxes(3,2) = sgn*m_dAxes(2,1);
00525 m_dAxes(3,3) = 0.;
00526 thp = 0.;
00527 for ( Int_t i = 0; i < np; i++ ) {
00528 thp += mom(i,5)*TMath::Abs(m_dAxes(3,1)*mom(i,1) +
00529 m_dAxes(3,2)*mom(i,2));
00530 }
00531 m_dThrust[3] = thp/tmax;
00532
00533 for ( Int_t i6 = 0; i6 < 3; i6++ ) {
00534 for ( Int_t j = 1; j < 4; j++ ) {
00535 temp(i6,j) = m_dAxes(i6+1,j);
00536 }
00537 temp(i6,4) = 0;
00538 }
00539 ludbrb(&temp,the,phi,0.,0.,0.);
00540 for ( Int_t i7 = 0; i7 < 3; i7++ ) {
00541 for ( Int_t j = 1; j < 4; j++ ) {
00542 m_dAxes(i7+1,j) = temp(i7,j);
00543 }
00544 }
00545 m_dOblateness = m_dThrust[2] - m_dThrust[3];
00546
00547
00548
00549
00550 CalcWmul();
00551 CalcHTstuff();
00552 CalcSqrts();
00553
00554 }
00555
00556
00557
00558
00559 void TopologyWorker::setThMomPower(double tp)
00560 {
00561
00562 if ( tp > 0. ) m_dDeltaThPower = tp - 1.0;
00563 return;
00564 }
00565
00566
00567 double TopologyWorker::getThMomPower()
00568 {
00569 return 1.0 + m_dDeltaThPower;
00570 }
00571
00572
00573 void TopologyWorker::setFast(Int_t nf)
00574 {
00575
00576 if ( nf > 3 ) m_iFast = nf;
00577 return;
00578 }
00579
00580
00581 Int_t TopologyWorker::getFast()
00582 {
00583 return m_iFast;
00584 }
00585
00586
00587
00588
00589 TVector3 TopologyWorker::thrustAxis() {
00590 TVector3 m_ThrustAxis(m_dAxes(1,1),m_dAxes(1,2),m_dAxes(1,3));
00591 return m_ThrustAxis;
00592 }
00593
00594
00595 TVector3 TopologyWorker::majorAxis() {
00596 TVector3 m_MajorAxis(m_dAxes(2,1),m_dAxes(2,2),m_dAxes(2,3));
00597 return m_MajorAxis;
00598 }
00599
00600
00601 TVector3 TopologyWorker::minorAxis() {
00602 TVector3 m_MinorAxis(m_dAxes(3,1),m_dAxes(3,2),m_dAxes(3,3));
00603 return m_MinorAxis;
00604 }
00605
00606
00607 TVector3 TopologyWorker::thrust() {
00608 TVector3 m_Thrust(m_dThrust[1],m_dThrust[2],m_dThrust[3]);
00609 return m_Thrust;
00610 }
00611
00612
00613 double TopologyWorker::oblateness() {
00614 return m_dOblateness;
00615 }
00616
00617
00618
00619 double TopologyWorker::ulAngle(double x, double y)
00620 {
00621 double ulangl = 0;
00622 double r = TMath::Sqrt(x*x + y*y);
00623 if ( r < 1.0E-20 ) {
00624 return ulangl;
00625 }
00626 if ( TMath::Abs(x)/r < 0.8 ) {
00627 ulangl = sign(TMath::ACos(x/r),y);
00628 }
00629 else {
00630 ulangl = TMath::ASin(y/r);
00631 if ( x < 0. && ulangl >= 0. ) {
00632 ulangl = TMath::Pi() - ulangl;
00633 }
00634 else if ( x < 0. ) {
00635 ulangl = -TMath::Pi() - ulangl;
00636 }
00637 }
00638 return ulangl;
00639 }
00640
00641
00642 double TopologyWorker::sign(double a, double b) {
00643 if ( b < 0 ) {
00644 return -TMath::Abs(a);
00645 }
00646 else {
00647 return TMath::Abs(a);
00648 }
00649 }
00650
00651
00652 void TopologyWorker::ludbrb(TMatrix* mom,
00653 double the,
00654 double phi,
00655 double bx,
00656 double by,
00657 double bz)
00658 {
00659
00660
00661 TMatrix rot(4,4);
00662 double pr[4];
00663 double dp[5];
00664 Int_t np = mom->GetNrows();
00665 if ( the*the + phi*phi > 1.0E-20 )
00666 {
00667 rot(1,1) = TMath::Cos(the)*TMath::Cos(phi);
00668 rot(1,2) = -TMath::Sin(phi);
00669 rot(1,3) = TMath::Sin(the)*TMath::Cos(phi);
00670 rot(2,1) = TMath::Cos(the)*TMath::Sin(phi);
00671 rot(2,2) = TMath::Cos(phi);
00672 rot(2,3) = TMath::Sin(the)*TMath::Sin(phi);
00673 rot(3,1) = -TMath::Sin(the);
00674 rot(3,2) = 0.0;
00675 rot(3,3) = TMath::Cos(the);
00676 for ( Int_t i = 0; i < np; i++ )
00677 {
00678 for ( Int_t j = 1; j < 4; j++ )
00679 {
00680 pr[j] = (*mom)(i,j);
00681 (*mom)(i,j) = 0;
00682 }
00683 for ( Int_t jb = 1; jb < 4; jb++)
00684 {
00685 for ( Int_t k = 1; k < 4; k++)
00686 {
00687 (*mom)(i,jb) = (*mom)(i,jb) + rot(jb,k)*pr[k];
00688 }
00689 }
00690 }
00691 double beta = TMath::Sqrt( bx*bx + by*by + bz*bz );
00692 if ( beta*beta > 1.0E-20 )
00693 {
00694 if ( beta > 0.99999999 )
00695 {
00696
00697 bx = bx*(0.99999999/beta);
00698 by = by*(0.99999999/beta);
00699 bz = bz*(0.99999999/beta);
00700 beta = 0.99999999;
00701 }
00702 double gamma = 1.0/TMath::Sqrt(1.0 - beta*beta);
00703 for ( Int_t i = 0; i < np; i++ )
00704 {
00705 for ( Int_t j = 1; j < 5; j++ )
00706 {
00707 dp[j] = (*mom)(i,j);
00708 }
00709 double bp = bx*dp[1] + by*dp[2] + bz*dp[3];
00710 double gbp = gamma*(gamma*bp/(1.0 + gamma) + dp[4]);
00711 (*mom)(i,1) = dp[1] + gbp*bx;
00712 (*mom)(i,2) = dp[2] + gbp*by;
00713 (*mom)(i,3) = dp[3] + gbp*bz;
00714 (*mom)(i,4) = gamma*(dp[4] + bp);
00715 }
00716 }
00717 }
00718 return;
00719 }
00720
00721
00722
00723
00724
00725 void TopologyWorker::sanda() {
00726 float SPH=-1;
00727 float APL=-1;
00728 m_sanda_called=true;
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 float P[1000][6];
00745 double SM[4][4],SV[4][4];
00746 double PA,PWT,PS,SQ,SR,SP,SMAX,SGN;
00747 int NP;
00748 int J, J1, J2, I, N, JA, JB, J3, JC, JB1, JB2;
00749 JA=JB=JC=0;
00750 double RL;
00751 float rlu,rlu1;
00752
00753
00754
00755 N=m_np;
00756 NP=0;
00757 for (I=1;I<N+1;I++){
00758 NP++;
00759 P[NP][1]=m_mom(I-1,1) ;
00760 P[NP][2]=m_mom(I-1,2) ;
00761 P[NP][3]=m_mom(I-1,3) ;
00762 P[NP][4]=m_mom(I-1,4) ;
00763 P[NP][5]=0;
00764 }
00765
00766
00767
00768 N=NP;
00769
00770 for (J1=1;J1<4;J1++) {
00771 for (J2=J1;J2<4;J2++) {
00772 SM[J1][J2]=0.;
00773 }
00774 }
00775 PS=0.;
00776 for (I=1;I<N+1;I++) {
00777 PA=sqrt(pow(P[I][1],2)+pow(P[I][2],2)+pow(P[I][3],2));
00778 PWT=1.;
00779 for (J1=1;J1<4;J1++) {
00780 for (J2=J1;J2<4;J2++) {
00781 SM[J1][J2]=SM[J1][J2]+PWT*P[I][J1]*P[I][J2];
00782 }
00783 }
00784 PS=PS+PWT*PA*PA;
00785 }
00786
00787 if(NP<2) {
00788 SPH=-1.;
00789 APL=-1.;
00790 return;
00791 }
00792 for (J1=1;J1<4;J1++) {
00793 for (J2=J1;J2<4;J2++) {
00794 SM[J1][J2]=SM[J1][J2]/PS;
00795 }
00796 }
00797
00798 SQ=(SM[1][1]*SM[2][2]+SM[1][1]*SM[3][3]+SM[2][2]*SM[3][3]
00799 -pow(SM[1][2],2)
00800 -pow(SM[1][3],2)-pow(SM[2][3],2))/3.-1./9.;
00801 SR=-0.5*(SQ+1./9.+SM[1][1]*pow(SM[2][3],2)+SM[2][2]*pow(SM[1][3],2)+SM[3][3]*
00802 pow(SM[1][2],2)-SM[1][1]*SM[2][2]*SM[3][3])+SM[1][2]*SM[1][3]*SM[2][3]+1./27.;
00803
00804 SP=TMath::Cos(TMath::ACos(TMath::Max(TMath::Min(SR/TMath::Sqrt(-pow(SQ,3)),1.),-1.))/3.);
00805
00806 P[N+1][4]=1./3.+TMath::Sqrt(-SQ)*TMath::Max(2.*SP,TMath::Sqrt(3.*(1.-SP*SP))-SP);
00807 P[N+3][4]=1./3.+TMath::Sqrt(-SQ)*TMath::Min(2.*SP,-TMath::Sqrt(3.*(1.-SP*SP))-SP);
00808 P[N+2][4]=1.-P[N+1][4]-P[N+3][4];
00809 if (P[N+2][4]> 1E-5) {
00810
00811
00812 for (I=1;I<4;I=I+2) {
00813 for (J1=1;J1<4;J1++) {
00814 SV[J1][J1]=SM[J1][J1]-P[N+I][4];
00815 for (J2=J1+1;J2<4;J2++) {
00816 SV[J1][J2]=SM[J1][J2];
00817 SV[J2][J1]=SM[J1][J2];
00818 }
00819 }
00820 SMAX=0.;
00821 for (J1=1;J1<4;J1++) {
00822 for (J2=1;J2<4;J2++) {
00823 if(std::fabs(SV[J1][J2])>SMAX) {
00824 JA=J1;
00825 JB=J2;
00826 SMAX=std::fabs(SV[J1][J2]);
00827 }
00828 }
00829 }
00830 SMAX=0.;
00831 for (J3=JA+1;J3<JA+3;J3++) {
00832 J1=J3-3*((J3-1)/3);
00833 RL=SV[J1][JB]/SV[JA][JB];
00834 for (J2=1;J2<4;J2++) {
00835 SV[J1][J2]=SV[J1][J2]-RL*SV[JA][J2];
00836 if (std::fabs(SV[J1][J2])>SMAX) {
00837 JC=J1;
00838 SMAX=std::fabs(SV[J1][J2]);
00839 }
00840 }
00841 }
00842 JB1=JB+1-3*(JB/3);
00843 JB2=JB+2-3*((JB+1)/3);
00844 P[N+I][JB1]=-SV[JC][JB2];
00845 P[N+I][JB2]=SV[JC][JB1];
00846 P[N+I][JB]=-(SV[JA][JB1]*P[N+I][JB1]+SV[JA][JB2]*P[N+I][JB2])/
00847 SV[JA][JB];
00848 PA=TMath::Sqrt(pow(P[N+I][1],2)+pow(P[N+I][2],2)+pow(P[N+I][3],2));
00849
00850 float pa=P[N-1][I];
00851 rlu=std::fabs(pa)-std::fabs(int(pa)*1.);
00852 rlu1=std::fabs(pa*pa)-std::fabs(int(pa*pa)*1.);
00853 SGN=pow((-1.),1.*int(rlu+0.5));
00854 for (J=1;J<4;J++) {
00855 P[N+I][J]=SGN*P[N+I][J]/PA;
00856 }
00857 }
00858
00859
00860 SGN=pow((-1.),1.*int(rlu1+0.5));
00861 P[N+2][1]=SGN*(P[N+1][2]*P[N+3][3]-P[N+1][3]*P[N+3][2]);
00862 P[N+2][2]=SGN*(P[N+1][3]*P[N+3][1]-P[N+1][1]*P[N+3][3]);
00863 P[N+2][3]=SGN*(P[N+1][1]*P[N+3][2]-P[N+1][2]*P[N+3][1]);
00864
00865
00866 SPH=1.5*(P[N+2][4]+P[N+3][4]);
00867 APL=1.5*P[N+3][4];
00868
00869 }
00870
00871 m_sph=SPH;
00872 m_apl=APL;
00873 return;
00874 }
00875
00876
00877
00878
00879 void TopologyWorker::planes_sphe(double& pnorm, double& p2, double& p3) {
00880
00881
00882
00883 float P[1000][6];
00884 double SM[4][4],SV[4][4];
00885 double PA,PWT,PS,SQ,SR,SP,SMAX,SGN;
00886 int NP;
00887 int J, J1, J2, I, N, JA, JB, J3, JC, JB1, JB2;
00888 JA=JB=JC=0;
00889 double RL;
00890 float rlu,rlu1;
00891
00892
00893
00894 N=m_np;
00895 NP=0;
00896 for (I=1;I<N+1;I++){
00897 NP++;
00898 P[NP][1]=m_mom(I-1,1) ;
00899 P[NP][2]=m_mom(I-1,2) ;
00900 P[NP][3]=m_mom(I-1,3) ;
00901 P[NP][4]=m_mom(I-1,4) ;
00902 P[NP][5]=0;
00903 }
00904
00905
00906
00907 N=NP;
00908
00909 for (J1=1;J1<4;J1++) {
00910 for (J2=J1;J2<4;J2++) {
00911 SM[J1][J2]=0.;
00912 }
00913 }
00914 PS=0.;
00915 for (I=1;I<N+1;I++) {
00916 PA=sqrt(pow(P[I][1],2)+pow(P[I][2],2)+pow(P[I][3],2));
00917 double eta,phi;
00918 getetaphi(P[I][1],P[I][2],P[I][3],eta,phi);
00919 PWT=exp(-std::fabs(eta));
00920 PWT=1.;
00921 for (J1=1;J1<4;J1++) {
00922 for (J2=J1;J2<4;J2++) {
00923 SM[J1][J2]=SM[J1][J2]+PWT*P[I][J1]*P[I][J2];
00924 }
00925 }
00926 PS=PS+PWT*PA*PA;
00927 }
00928
00929 if(NP<2) {
00930
00931
00932 return;
00933 }
00934 for (J1=1;J1<4;J1++) {
00935 for (J2=J1;J2<4;J2++) {
00936 SM[J1][J2]=SM[J1][J2]/PS;
00937 }
00938 }
00939
00940 SQ=(SM[1][1]*SM[2][2]+SM[1][1]*SM[3][3]+SM[2][2]*SM[3][3]
00941 -pow(SM[1][2],2)
00942 -pow(SM[1][3],2)-pow(SM[2][3],2))/3.-1./9.;
00943 SR=-0.5*(SQ+1./9.+SM[1][1]*pow(SM[2][3],2)+SM[2][2]*pow(SM[1][3],2)+SM[3][3]*
00944 pow(SM[1][2],2)-SM[1][1]*SM[2][2]*SM[3][3])+SM[1][2]*SM[1][3]*SM[2][3]+1./27.;
00945
00946 SP=TMath::Cos(TMath::ACos(TMath::Max(TMath::Min(SR/TMath::Sqrt(-pow(SQ,3)),1.),-1.))/3.);
00947
00948 P[N+1][4]=1./3.+TMath::Sqrt(-SQ)*TMath::Max(2.*SP,TMath::Sqrt(3.*(1.-SP*SP))-SP);
00949 P[N+3][4]=1./3.+TMath::Sqrt(-SQ)*TMath::Min(2.*SP,-TMath::Sqrt(3.*(1.-SP*SP))-SP);
00950 P[N+2][4]=1.-P[N+1][4]-P[N+3][4];
00951 if (P[N+2][4]> 1E-5) {
00952
00953
00954 for (I=1;I<4;I=I+2) {
00955 for (J1=1;J1<4;J1++) {
00956 SV[J1][J1]=SM[J1][J1]-P[N+I][4];
00957 for (J2=J1+1;J2<4;J2++) {
00958 SV[J1][J2]=SM[J1][J2];
00959 SV[J2][J1]=SM[J1][J2];
00960 }
00961 }
00962 SMAX=0.;
00963 for (J1=1;J1<4;J1++) {
00964 for (J2=1;J2<4;J2++) {
00965 if(std::fabs(SV[J1][J2])>SMAX) {
00966 JA=J1;
00967 JB=J2;
00968 SMAX=std::fabs(SV[J1][J2]);
00969 }
00970 }
00971 }
00972 SMAX=0.;
00973 for (J3=JA+1;J3<JA+3;J3++) {
00974 J1=J3-3*((J3-1)/3);
00975 RL=SV[J1][JB]/SV[JA][JB];
00976 for (J2=1;J2<4;J2++) {
00977 SV[J1][J2]=SV[J1][J2]-RL*SV[JA][J2];
00978 if (std::fabs(SV[J1][J2])>SMAX) {
00979 JC=J1;
00980 SMAX=std::fabs(SV[J1][J2]);
00981 }
00982 }
00983 }
00984 JB1=JB+1-3*(JB/3);
00985 JB2=JB+2-3*((JB+1)/3);
00986 P[N+I][JB1]=-SV[JC][JB2];
00987 P[N+I][JB2]=SV[JC][JB1];
00988 P[N+I][JB]=-(SV[JA][JB1]*P[N+I][JB1]+SV[JA][JB2]*P[N+I][JB2])/
00989 SV[JA][JB];
00990 PA=TMath::Sqrt(pow(P[N+I][1],2)+pow(P[N+I][2],2)+pow(P[N+I][3],2));
00991
00992 float pa=P[N-1][I];
00993 rlu=std::fabs(pa)-std::fabs(int(pa)*1.);
00994 rlu1=std::fabs(pa*pa)-std::fabs(int(pa*pa)*1.);
00995 SGN=pow((-1.),1.*int(rlu+0.5));
00996 for (J=1;J<4;J++) {
00997 P[N+I][J]=SGN*P[N+I][J]/PA;
00998 }
00999 }
01000
01001
01002 SGN=pow((-1.),1.*int(rlu1+0.5));
01003 P[N+2][1]=SGN*(P[N+1][2]*P[N+3][3]-P[N+1][3]*P[N+3][2]);
01004 P[N+2][2]=SGN*(P[N+1][3]*P[N+3][1]-P[N+1][1]*P[N+3][3]);
01005 P[N+2][3]=SGN*(P[N+1][1]*P[N+3][2]-P[N+1][2]*P[N+3][1]);
01006
01007
01008
01009
01010
01011 }
01012
01013
01014 double etstot[4];
01015 double eltot[4];
01016 double sum23=0;
01017 double sum22=0;
01018 double sum33=0;
01019 double pina[4];
01020 double ax[4], ay[4], az[4];
01021 for (int ia=1;ia<4;ia++) {
01022 etstot[ia]=0;
01023 eltot[ia]=0;
01024 pina[ia]=0;
01025 ax[ia]=P[N+ia][1];
01026 ay[ia]=P[N+ia][2];
01027 az[ia]=P[N+ia][3];
01028 ax[ia]/=sqrt(ax[ia]*ax[ia]+ay[ia]*ay[ia]+az[ia]*az[ia]);
01029 ay[ia]/=sqrt(ax[ia]*ax[ia]+ay[ia]*ay[ia]+az[ia]*az[ia]);
01030 az[ia]/=sqrt(ax[ia]*ax[ia]+ay[ia]*ay[ia]+az[ia]*az[ia]);
01031 }
01032
01033
01034 for (int k =0 ; k<m_np ; k++) {
01035
01036
01037 double W=1.0;
01038 for (int ia=1;ia<4;ia++) {
01039 double e=sqrt(m_mom(k,1)*m_mom(k,1) +
01040 m_mom(k,2)*m_mom(k,2) +
01041 m_mom(k,3)*m_mom(k,3));
01042 double el=ax[ia]*m_mom(k,1) + ay[ia]*m_mom(k,2) + az[ia]*m_mom(k,3);
01043 pina[ia]=el;
01044 double ets=(e*e-el*el);
01045 etstot[ia]+=ets*W;
01046 eltot[ia]+=el*el;
01047 }
01048 double a2=pina[2];
01049 double a3=pina[3];
01050
01051
01052
01053 sum22+=a2*a2*W;
01054 sum23+=a2*a3*W;
01055 sum33+=a3*a3*W;
01056 }
01057
01058
01059
01060 double pi=3.1415927;
01061 double phi=pi/2.0;
01062 double phip=pi/2.0;
01063 double a=sum23;
01064 double c=-a;
01065 double b=sum22-sum33;
01066 double disc=b*b-4*a*c;
01067
01068 if (disc>=0) {
01069 double x1=(sqrt(disc)-b)/2/a;
01070 double x2=(-sqrt(disc)-b)/2/a;
01071 phi=atan(x1);
01072 phip=atan(x2);
01073 if (phi<0) phi=2.*pi+phi;
01074 if (phip<0) phip=2.*pi+phip;
01075 }
01076 double p21=sum22*cos(phi)*cos(phi)+sum33*sin(phi)*sin(phi)+2*sum23*cos(phi)*sin(phi);
01077 double p31=sum22*sin(phi)*sin(phi)+sum33*cos(phi)*cos(phi)-2*sum23*cos(phi)*sin(phi);
01078
01079 double p22=sum22*cos(phip)*cos(phip)+sum33*sin(phip)*sin(phip)+2*sum23*cos(phip)*sin(phip);
01080 double p32=sum22*sin(phip)*sin(phip)+sum33*cos(phip)*cos(phip)-2*sum23*cos(phip)*sin(phip);
01081
01082
01083 double d1=std::fabs(p31*p31 - p21*p21);
01084 double d2=std::fabs(p32*p32 - p22*p22);
01085
01086
01087
01088 p2=p21;
01089 p3=p31;
01090 if (d2>d1) {
01091 p2=p22;
01092 p3=p32;
01093 }
01094 pnorm=sqrt(eltot[1]);
01095 if (p2>p3) {
01096 p3=sqrt(p3);
01097 p2=sqrt(p2);
01098 }else {
01099 double p4=p3;
01100 p3=sqrt(p2);
01101 p2=sqrt(p4);
01102 }
01103
01104
01105
01106
01107
01108
01109
01110 return;
01111 }
01112
01113
01114 void TopologyWorker::planes_sphe_wei(double& pnorm, double& p2, double& p3) {
01115
01116
01117
01118 float P[1000][6];
01119 double SM[4][4],SV[4][4];
01120 double PA,PWT,PS,SQ,SR,SP,SMAX,SGN;
01121 int NP;
01122 int J, J1, J2, I, N, JA, JB, J3, JC, JB1, JB2;
01123 JA=JB=JC=0;
01124 double RL;
01125 float rlu,rlu1;
01126
01127
01128
01129 N=m_np;
01130 NP=0;
01131 for (I=1;I<N+1;I++){
01132 NP++;
01133 P[NP][1]=m_mom(I-1,1) ;
01134 P[NP][2]=m_mom(I-1,2) ;
01135 P[NP][3]=m_mom(I-1,3) ;
01136 P[NP][4]=m_mom(I-1,4) ;
01137 P[NP][5]=0;
01138 }
01139
01140
01141
01142 N=NP;
01143
01144 for (J1=1;J1<4;J1++) {
01145 for (J2=J1;J2<4;J2++) {
01146 SM[J1][J2]=0.;
01147 }
01148 }
01149 PS=0.;
01150 for (I=1;I<N+1;I++) {
01151 PA=sqrt(pow(P[I][1],2)+pow(P[I][2],2)+pow(P[I][3],2));
01152
01153
01154
01155 PWT=1.;
01156 for (J1=1;J1<4;J1++) {
01157 for (J2=J1;J2<4;J2++) {
01158 SM[J1][J2]=SM[J1][J2]+PWT*P[I][J1]*P[I][J2];
01159 }
01160 }
01161 PS=PS+PWT*PA*PA;
01162 }
01163
01164 if(NP<2) {
01165
01166
01167 return;
01168 }
01169 for (J1=1;J1<4;J1++) {
01170 for (J2=J1;J2<4;J2++) {
01171 SM[J1][J2]=SM[J1][J2]/PS;
01172 }
01173 }
01174
01175 SQ=(SM[1][1]*SM[2][2]+SM[1][1]*SM[3][3]+SM[2][2]*SM[3][3]
01176 -pow(SM[1][2],2)
01177 -pow(SM[1][3],2)-pow(SM[2][3],2))/3.-1./9.;
01178 SR=-0.5*(SQ+1./9.+SM[1][1]*pow(SM[2][3],2)+SM[2][2]*pow(SM[1][3],2)+SM[3][3]*
01179 pow(SM[1][2],2)-SM[1][1]*SM[2][2]*SM[3][3])+SM[1][2]*SM[1][3]*SM[2][3]+1./27.;
01180
01181 SP=TMath::Cos(TMath::ACos(TMath::Max(TMath::Min(SR/TMath::Sqrt(-pow(SQ,3)),1.),-1.))/3.);
01182
01183 P[N+1][4]=1./3.+TMath::Sqrt(-SQ)*TMath::Max(2.*SP,TMath::Sqrt(3.*(1.-SP*SP))-SP);
01184 P[N+3][4]=1./3.+TMath::Sqrt(-SQ)*TMath::Min(2.*SP,-TMath::Sqrt(3.*(1.-SP*SP))-SP);
01185 P[N+2][4]=1.-P[N+1][4]-P[N+3][4];
01186 if (P[N+2][4]> 1E-5) {
01187
01188
01189 for (I=1;I<4;I=I+2) {
01190 for (J1=1;J1<4;J1++) {
01191 SV[J1][J1]=SM[J1][J1]-P[N+I][4];
01192 for (J2=J1+1;J2<4;J2++) {
01193 SV[J1][J2]=SM[J1][J2];
01194 SV[J2][J1]=SM[J1][J2];
01195 }
01196 }
01197 SMAX=0.;
01198 for (J1=1;J1<4;J1++) {
01199 for (J2=1;J2<4;J2++) {
01200 if(std::fabs(SV[J1][J2])>SMAX) {
01201 JA=J1;
01202 JB=J2;
01203 SMAX=std::fabs(SV[J1][J2]);
01204 }
01205 }
01206 }
01207 SMAX=0.;
01208 for (J3=JA+1;J3<JA+3;J3++) {
01209 J1=J3-3*((J3-1)/3);
01210 RL=SV[J1][JB]/SV[JA][JB];
01211 for (J2=1;J2<4;J2++) {
01212 SV[J1][J2]=SV[J1][J2]-RL*SV[JA][J2];
01213 if (std::fabs(SV[J1][J2])>SMAX) {
01214 JC=J1;
01215 SMAX=std::fabs(SV[J1][J2]);
01216 }
01217 }
01218 }
01219 JB1=JB+1-3*(JB/3);
01220 JB2=JB+2-3*((JB+1)/3);
01221 P[N+I][JB1]=-SV[JC][JB2];
01222 P[N+I][JB2]=SV[JC][JB1];
01223 P[N+I][JB]=-(SV[JA][JB1]*P[N+I][JB1]+SV[JA][JB2]*P[N+I][JB2])/
01224 SV[JA][JB];
01225 PA=TMath::Sqrt(pow(P[N+I][1],2)+pow(P[N+I][2],2)+pow(P[N+I][3],2));
01226
01227 float pa=P[N-1][I];
01228 rlu=std::fabs(pa)-std::fabs(int(pa)*1.);
01229 rlu1=std::fabs(pa*pa)-std::fabs(int(pa*pa)*1.);
01230 SGN=pow((-1.),1.*int(rlu+0.5));
01231 for (J=1;J<4;J++) {
01232 P[N+I][J]=SGN*P[N+I][J]/PA;
01233 }
01234 }
01235
01236
01237 SGN=pow((-1.),1.*int(rlu1+0.5));
01238 P[N+2][1]=SGN*(P[N+1][2]*P[N+3][3]-P[N+1][3]*P[N+3][2]);
01239 P[N+2][2]=SGN*(P[N+1][3]*P[N+3][1]-P[N+1][1]*P[N+3][3]);
01240 P[N+2][3]=SGN*(P[N+1][1]*P[N+3][2]-P[N+1][2]*P[N+3][1]);
01241
01242
01243
01244
01245
01246 }
01247
01248
01249 double etstot[4];
01250 double eltot[4];
01251 double sum23=0;
01252 double sum22=0;
01253 double sum33=0;
01254 double pina[4];
01255 double ax[4], ay[4], az[4];
01256 for (int ia=1;ia<4;ia++) {
01257 etstot[ia]=0;
01258 eltot[ia]=0;
01259 pina[ia]=0;
01260 ax[ia]=P[N+ia][1];
01261 ay[ia]=P[N+ia][2];
01262 az[ia]=P[N+ia][3];
01263 ax[ia]/=sqrt(ax[ia]*ax[ia]+ay[ia]*ay[ia]+az[ia]*az[ia]);
01264 ay[ia]/=sqrt(ax[ia]*ax[ia]+ay[ia]*ay[ia]+az[ia]*az[ia]);
01265 az[ia]/=sqrt(ax[ia]*ax[ia]+ay[ia]*ay[ia]+az[ia]*az[ia]);
01266 }
01267
01268 for (int k =0 ; k<m_np ; k++) {
01269 double eta,phi;
01270 getetaphi(m_mom(k,1),m_mom(k,2),m_mom(k,3),eta,phi);
01271 double W=exp(-std::fabs(eta*1.0));
01272 for (int ia=1;ia<4;ia++) {
01273 double e=sqrt(m_mom(k,1)*m_mom(k,1) +
01274 m_mom(k,2)*m_mom(k,2) +
01275 m_mom(k,3)*m_mom(k,3));
01276 double el=ax[ia]*m_mom(k,1) + ay[ia]*m_mom(k,2) + az[ia]*m_mom(k,3);
01277 pina[ia]=el;
01278 double ets=(e*e-el*el);
01279 etstot[ia]+=ets*W;
01280 eltot[ia]+=el*el*W;
01281 }
01282 double a2=pina[2];
01283 double a3=pina[3];
01284
01285
01286
01287 sum22+=a2*a2*W;
01288 sum23+=a2*a3*W;
01289 sum33+=a3*a3*W;
01290 }
01291
01292
01293 double pi=3.1415927;
01294 double phi=pi/2.0;
01295 double phip=pi/2.0;
01296 double a=sum23;
01297 double c=-a;
01298 double b=sum22-sum33;
01299 double disc=b*b-4*a*c;
01300
01301 if (disc>=0) {
01302 double x1=(sqrt(disc)-b)/2/a;
01303 double x2=(-sqrt(disc)-b)/2/a;
01304 phi=atan(x1);
01305 phip=atan(x2);
01306 if (phi<0) phi=2.*pi+phi;
01307 if (phip<0) phip=2.*pi+phip;
01308 }
01309 double p21=sum22*cos(phi)*cos(phi)+sum33*sin(phi)*sin(phi)+2*sum23*cos(phi)*sin(phi);
01310 double p31=sum22*sin(phi)*sin(phi)+sum33*cos(phi)*cos(phi)-2*sum23*cos(phi)*sin(phi);
01311
01312 double p22=sum22*cos(phip)*cos(phip)+sum33*sin(phip)*sin(phip)+2*sum23*cos(phip)*sin(phip);
01313 double p32=sum22*sin(phip)*sin(phip)+sum33*cos(phip)*cos(phip)-2*sum23*cos(phip)*sin(phip);
01314
01315
01316 double d1=std::fabs(p31*p31 - p21*p21);
01317 double d2=std::fabs(p32*p32 - p22*p22);
01318
01319
01320
01321 p2=p21;
01322 p3=p31;
01323 if (d2>d1) {
01324 p2=p22;
01325 p3=p32;
01326 }
01327 pnorm=sqrt(eltot[1]);
01328 if (p2>p3) {
01329 p3=sqrt(p3);
01330 p2=sqrt(p2);
01331 }else {
01332 double p4=p3;
01333 p3=sqrt(p2);
01334 p2=sqrt(p4);
01335 }
01336
01337
01338
01339
01340
01341
01342
01343 return;
01344 }
01345
01346
01347
01348 void TopologyWorker::planes_thrust(double& pnorm, double& p2, double& p3) {
01349 TVector3 thrustaxis=thrustAxis();
01350 TVector3 majoraxis=majorAxis();
01351 TVector3 minoraxis=minorAxis();
01352
01353 double etstot[4];
01354 double eltot[4];
01355 double sum23=0;
01356 double sum22=0;
01357 double sum33=0;
01358 double pina[4];
01359 double ax[4], ay[4], az[4];
01360 ax[1]=thrustaxis(0); ay[1]=thrustaxis(1); az[1]=thrustaxis(2);
01361 ax[2]=minoraxis(0); ay[2]=minoraxis(1); az[2]=minoraxis(2);
01362 ax[3]=majoraxis(0); ay[3]=majoraxis(1); az[3]=majoraxis(2);
01363 for (int ia=1;ia<4;ia++) {
01364 etstot[ia]=0;
01365 eltot[ia]=0;
01366 pina[ia]=0;
01367 ax[ia]/=sqrt(ax[ia]*ax[ia]+ay[ia]*ay[ia]+az[ia]*az[ia]);
01368 ay[ia]/=sqrt(ax[ia]*ax[ia]+ay[ia]*ay[ia]+az[ia]*az[ia]);
01369 az[ia]/=sqrt(ax[ia]*ax[ia]+ay[ia]*ay[ia]+az[ia]*az[ia]);
01370 }
01371
01372 for (int k =0 ; k<m_np ; k++) {
01373 for (int ia=1;ia<4;ia++) {
01374 double e=sqrt(m_mom(k,1)*m_mom(k,1) +
01375 m_mom(k,2)*m_mom(k,2) +
01376 m_mom(k,3)*m_mom(k,3));
01377 double el=ax[ia]*m_mom(k,1) + ay[ia]*m_mom(k,2) + az[ia]*m_mom(k,3);
01378 pina[ia]=el;
01379 double ets=(e*e-el*el);
01380 etstot[ia]+=ets;
01381 eltot[ia]+=std::fabs(el);
01382 }
01383 double a2=pina[2];
01384 double a3=pina[3];
01385
01386
01387
01388 sum22+=a2*a2;
01389 sum23+=a2*a3;
01390 sum33+=a3*a3;
01391 }
01392
01393
01394 double pi=3.1415927;
01395 double phi=pi/2.0;
01396 double phip=pi/2.0;
01397 double a=sum23;
01398 double c=-a;
01399 double b=sum22-sum33;
01400 double disc=b*b-4*a*c;
01401
01402 if (disc>=0) {
01403 double x1=(sqrt(disc)-b)/2/a;
01404 double x2=(-sqrt(disc)-b)/2/a;
01405 phi=atan(x1);
01406 phip=atan(x2);
01407 if (phi<0) phi=2.*pi+phi;
01408 if (phip<0) phip=2.*pi+phip;
01409 }
01410 double p21=sum22*cos(phi)*cos(phi)+sum33*sin(phi)*sin(phi)+2*sum23*cos(phi)*sin(phi);
01411 double p31=sum22*sin(phi)*sin(phi)+sum33*cos(phi)*cos(phi)-2*sum23*cos(phi)*sin(phi);
01412
01413 double p22=sum22*cos(phip)*cos(phip)+sum33*sin(phip)*sin(phip)+2*sum23*cos(phip)*sin(phip);
01414 double p32=sum22*sin(phip)*sin(phip)+sum33*cos(phip)*cos(phip)-2*sum23*cos(phip)*sin(phip);
01415
01416
01417 double d1=std::fabs(p31*p31 - p21*p21);
01418 double d2=std::fabs(p32*p32 - p22*p22);
01419
01420
01421
01422 p2=p21;
01423 p3=p31;
01424 if (d2>d1) {
01425 p2=p22;
01426 p3=p32;
01427 }
01428 pnorm=sqrt(etstot[1]);
01429 if (p2>p3) {
01430 p3=sqrt(p3);
01431 p2=sqrt(p2);
01432 }else {
01433 double p4=p3;
01434 p3=sqrt(p2);
01435 p2=sqrt(p4);
01436 }
01437
01438
01439
01440
01441 return;
01442 }
01443
01444
01445 void TopologyWorker::fowo() {
01446
01447 m_fowo_called=true;
01448
01449 float H10=-1;
01450 float H20=-1;
01451 float H30=-1;
01452 float H40=-1;
01453 float H50=-1;
01454 float H60=-1;
01455 if (1==1) {
01456 float P[1000][6],H0,HD,CTHE;
01457 int N,NP,I,J,I1,I2;
01458 H0=HD=0.;
01459 N=m_np;
01460 NP=0;
01461 for (I=1;I<N+1;I++){
01462 NP++;
01463 P[NP][1]=m_mom(I-1,1) ;
01464 P[NP][2]=m_mom(I-1,2) ;
01465 P[NP][3]=m_mom(I-1,3) ;
01466 P[NP][4]=m_mom(I-1,4) ;
01467 P[NP][5]=m_mom(I-1,5) ;
01468 }
01469
01470 N=NP;
01471 NP=0;
01472
01473 for (I=1;I<N+1;I++) {
01474 NP=NP+1;
01475 for (J=1;J<5;J++) {
01476 P[N+NP][J]=P[I][J];
01477 }
01478
01479 P[N+NP][4]=sqrt(pow(P[I][1],2)+pow(P[I][2],2)+pow(P[I][3],2));
01480
01481 P[N+NP][5]=sqrt(pow(P[I][1],2)+pow(P[I][2],2));
01482 H0=H0+P[N+NP][5];
01483 HD=HD+pow(P[N+NP][5],2);
01484 }
01485 H0=H0*H0;
01486
01487
01488
01489
01490 if (NP<2) {
01491 H10=-1.;
01492 H20=-1.;
01493 H30=-1.;
01494 H40=-1.;
01495 H50=-1.;
01496 H60=-1.;
01497 return;
01498 }
01499
01500
01501 H10=0.;
01502 H20=0.;
01503 H30=0.;
01504 H40=0.;
01505 H50=0.;
01506 H60=0.;
01507 for (I1=N+1;I1<N+NP+1;I1++) {
01508 for (I2=I1+1;I2<N+NP+1;I2++) {
01509 CTHE=(P[I1][1]*P[I2][1]+P[I1][2]*P[I2][2]+P[I1][3]*P[I2][3])/
01510 (P[I1][4]*P[I2][4]);
01511 H10=H10+P[I1][5]*P[I2][5]*CTHE;
01512 double C2=(1.5*CTHE*CTHE-0.5);
01513 H20=H20+P[I1][5]*P[I2][5]*C2;
01514 double C3=(2.5*CTHE*CTHE*CTHE-1.5*CTHE);
01515 H30=H30+P[I1][5]*P[I2][5]*C3;
01516
01517 double C4=(7*CTHE*C3 - 3*C2)/4.;
01518 double C5=(9*CTHE*C4 - 4*C3)/5.;
01519 double C6=(11*CTHE*C5 - 5*C4)/6.;
01520
01521
01522
01523
01524
01525 H40=H40+P[I1][5]*P[I2][5]*C4;
01526 H50=H50+P[I1][5]*P[I2][5]*C5;
01527 H60=H60+P[I1][5]*P[I2][5]*C6;
01528 }
01529 }
01530
01531 H10=(HD+2.*H10)/H0;
01532 H20=(HD+2.*H20)/H0;
01533 H30=(HD+2.*H30)/H0;
01534 H40=(HD+2.*H40)/H0;
01535 H50=(HD+2.*H50)/H0;
01536 H60=(HD+2.*H60)/H0;
01537 m_h10=H10;
01538 m_h20=H20;
01539 m_h30=H30;
01540 m_h40=H40;
01541 m_h50=H50;
01542 m_h60=H60;
01543 }
01544
01545 }
01546
01547 double TopologyWorker::get_h10() {
01548 if (!m_fowo_called) fowo();
01549 return m_h10;
01550 }
01551 double TopologyWorker::get_h20() {
01552 if (!m_fowo_called) fowo();
01553 return m_h20;
01554 }
01555 double TopologyWorker::get_h30() {
01556 if (!m_fowo_called) fowo();
01557 return m_h30;
01558 }
01559 double TopologyWorker::get_h40() {
01560 if (!m_fowo_called) fowo();
01561 return m_h40;
01562 }
01563
01564 double TopologyWorker::get_h50() {
01565 if (!m_fowo_called) fowo();
01566 return m_h50;
01567 }
01568 double TopologyWorker::get_h60() {
01569 if (!m_fowo_called) fowo();
01570 return m_h60;
01571 }
01572
01573
01574 double TopologyWorker::get_sphericity() {
01575 if (!m_sanda_called) sanda();
01576 return m_sph;
01577 }
01578 double TopologyWorker::get_aplanarity() {
01579 if (!m_sanda_called) sanda();
01580 return m_apl;
01581 }
01582
01583 void TopologyWorker::getetaphi(double px, double py, double pz, double& eta, double& phi) {
01584
01585 double pi=3.1415927;
01586
01587 double p=sqrt(px*px+py*py+pz*pz);
01588
01589 double th=pi/2.;
01590 if (p!=0) {
01591 th=acos(pz/p);
01592 }
01593 float thg=th;
01594 if (th<=0) {
01595 thg = pi + th;
01596 }
01597 eta=-9.;
01598 if (tan( thg/2.0 )>0.000001) {
01599 eta = -log( tan( thg/2.0 ) );
01600 }
01601 phi = atan2(py,px);
01602 if(phi<=0) phi += 2.0*pi;
01603 return;
01604 }
01605
01606
01607
01608 void TopologyWorker::sumangles(float& sdeta, float& sdr) {
01609 double eta1,eta2,phi1,phi2,deta,dphi,dr;
01610 m_sumangles_called=true;
01611 sdeta=0;
01612 sdr=0;
01613 for (int k=0;k<m_np;k++){
01614 for (int kp=k;kp<m_np;kp++){
01615 getetaphi(m_mom(k,1) , m_mom(k,2), m_mom(k,3), eta1,phi1);
01616 getetaphi(m_mom(kp,1) , m_mom(kp,2), m_mom(kp,3), eta2,phi2);
01617 dphi=std::fabs(phi1-phi2);
01618 if (dphi>3.1415) dphi=2*3.1415-dphi;
01619 deta=std::fabs(eta1-eta2);
01620 dr=sqrt(dphi*dphi+deta*deta);
01621 sdeta+=deta;
01622 sdr+=dr;
01623 }
01624 }
01625 return;
01626 }
01627
01628
01629
01630 Int_t TopologyWorker::iPow(Int_t man, Int_t exp)
01631 {
01632 Int_t ans = 1;
01633 for( Int_t k = 0; k < exp; k++)
01634 {
01635 ans = ans*man;
01636 }
01637 return ans;
01638 }
01639
01640
01641
01642 void TopologyWorker::CalcWmul(){
01643
01644 Int_t njets = m_np;
01645 double result=0;
01646 for(Int_t ijet=0; ijet<njets-1; ijet++){
01647 double emin=55;
01648 double emax=55;
01649 if(CalcPt(ijet)<55)
01650 emax=CalcPt(ijet);
01651 if(CalcPt(ijet+1)<55)
01652 emin=CalcPt(ijet+1);
01653 result+=0.5 * (emax*emax-emin*emin)*(ijet+1);
01654 }
01655 double elo=15;
01656 if(CalcPt(njets-1)>elo){
01657 elo=CalcPt(njets-1);
01658 }
01659
01660 result+=0.5 * (elo*elo-(15*15))*(njets);
01661 result/=((55*55)-100)/2.0;
01662 m_njetsweighed=result;
01663 }
01664
01665
01666
01667 void TopologyWorker::CalcSqrts(){
01668 TLorentzVector event(0,0,0,0);
01669 TLorentzVector worker(0,0,0,0);
01670
01671 for(int i=0; i< m_np; i++){
01672 double energy=m_mom(i,4);
01673 if(m_mom(i,4)<0.00001)
01674 energy=sqrt(pow(m_mom(i,1),2)+pow(m_mom(i,2),2)+pow(m_mom(i,3),2));
01675
01676 worker.SetXYZT(m_mom(i,1),m_mom(i,2),m_mom(i,3),energy);
01677 event+=worker;
01678 }
01679 m_sqrts=event.M();
01680 }
01681
01682
01683 void TopologyWorker::CalcHTstuff(){
01684 m_ht=0;
01685 m_ht3=0;
01686 m_et56=0;
01687 m_et0=0;
01688 double ptlead=0;
01689 double h=0;
01690 for(int i=0; i< m_np; i++){
01691
01692 m_ht+=CalcPt(i);
01693 h+=m_mom(i,4);
01694 if(i>1)
01695 m_ht3+=CalcPt(i);
01696 if(i==5)
01697 m_et56=sqrt(CalcPt(i)*CalcPt(i-1));
01698 }
01699
01700 for(int j=0; j< m_np2; j++){
01701
01702 if(ptlead<CalcPt2(j))
01703 ptlead=CalcPt2(j);
01704
01705 }
01706 if(m_ht>0.0001){
01707 m_et0=ptlead/m_ht;
01708
01709 }
01710 if(h>0.00001)
01711 m_centrality=m_ht/h;
01712 }
01713
01714 #endif
01715
01716
01717
01718