// $Id$ // // File: DTrack_factory_THROWN.cc // Created: Mon Sep 3 19:57:11 EDT 2007 // Creator: davidl (on Darwin Amelia.local 8.10.1 i386) // #include using namespace std; #include "DANA/DApplication.h" #include "DTrack_factory_THROWN.h" #include "DMCThrown.h" #include "DReferenceTrajectory.h" #include "DRandom.h" #include "DMatrix.h" //------------------ // evnt //------------------ jerror_t DTrack_factory_THROWN::evnt(JEventLoop *loop, int eventnumber) { vector mcthrowns; loop->Get(mcthrowns); for(unsigned int i=0; i< mcthrowns.size(); i++){ const DMCThrown *thrown = mcthrowns[i]; if(fabs(thrown->q)<1)continue; // Create new DTrack object and initialize parameters with those // from track candidate /* * Dave Lawrence's preliminary smearing algorithm. DTrack *track = new DTrack; track->q = thrown->q; track->p = thrown->p*(1.0+SampleGaussian(0.02)); track->theta = thrown->theta + SampleGaussian(0.001); if(track->theta<0.0)track->theta = 0.0; if(track->theta>=M_PI)track->theta = M_PI; track->phi = thrown->phi + SampleGaussian(0.002); if(track->phi<0.0)track->phi+=2.0*M_PI; if(track->phi>=2.0*M_PI)track->phi-=2.0*M_PI; track->x = thrown->x + SampleGaussian(0.01); track->y = thrown->y + SampleGaussian(0.01); track->z = thrown->z + SampleGaussian(1.00); track->candidateid = 0; track->chisq = 1.0; */ DTrack *track = new DTrack; track->q = thrown->q; track->candidateid = 0; track->chisq = 1.0; track->x = thrown->x; track->y = thrown->y; track->z = thrown->z; track->p = thrown->p; track->theta = thrown->theta; track->phi = thrown->phi; // Adapted from Alex's fortran code to paramatrize the resolution // of GlueX. He developed this from a study Dave Lawrence did. // Both the reference trajectory and the kinematic data section below // use DVector3 objects for position and momentum. DVector3 mom, pos; pos.SetXYZ(track->x, track->y, track->z); mom.SetMagThetaPhi(track->p, track->theta, track->phi); // We need to swim a reference trajectory here. To avoid the overhead // of allocating/deallocating them every event, we keep a pool and // re-use them. If the pool is not big enough, then add one to the // pool. if(rt.size()<=_data.size()){ // This is a little ugly, but only gets called a few times throughout the life of the process // Note: these never get deleted, even at the end of process. DApplication* dapp = dynamic_cast(loop->GetJApplication()); rt.push_back(new DReferenceTrajectory(dapp->GetBfield())); } rt[_data.size()]->Swim(pos, mom, track->q); track->rt = rt[_data.size()]; // Create and fill the covariance matrix for the track. // We need to fill this using errors estimated from the thrown // momentum and angle. DMatrixDSym errMatrix(1,7); // Fill in DKinematicData part track->setMass(0.0); track->setMomentum(mom); track->setPosition(pos); //track->setCharge(track->q); track->setErrorMatrix(errMatrix); this->SmearMomentum(track); _data.push_back(track); } return NOERROR; } //------------------ // SampleGaussian //------------------ double DTrack_factory_THROWN::SampleGaussian(double sigma) { // We loop to ensure not to return values greater than 3sigma away double val; do{ double epsilon = 1.0E-10; double r1 = epsilon+((double)random()/(double)RAND_MAX); double r2 = (double)random()/(double)RAND_MAX; val = sigma*sqrt(-2.0*log(r1))*cos(2.0*M_PI*r2); }while(fabs(val/sigma) > 3.0); return val; } //------------------ // toString //------------------ const string DTrack_factory_THROWN::toString(void) { // Ensure our Get method has been called so _data is up to date GetNrows(); if(_data.size()<=0)return string(); // don't print anything if we have no data! printheader("row: q: p: theta: phi: x: y: z:"); for(unsigned int i=0; i<_data.size(); i++){ DTrack *track = _data[i]; printnewrow(); printcol("%x", i); printcol("%+d", (int)track->q); printcol("%3.3f", track->p); printcol("%1.3f", track->theta); printcol("%1.3f", track->phi); printcol("%2.2f", track->x); printcol("%2.2f", track->y); printcol("%2.2f", track->z); printrow(); } return _table; } //------------------ // The various smearing resolutions taken // directly from Alex's smear.f code. //------------------ void DTrack_factory_THROWN::SmearMomentum(DTrack *trk) { DRandom rnd; // Track phi, theta, mag double pmag = trk->p; double phi = trk->phi; double theta = trk->theta; double theta_deg = theta*180.0/3.14159; rnd.SetSeed((uint)(1000*pmag)); double dp, dphi, dtheta, dtheta_deg; //cerr << "pmag/theta/theta_deg/phi: " << pmag << " " << theta << " " << theta_deg << " " << phi << endl; if(theta_deg<15) {dp=res_p1(theta_deg); dtheta_deg=res_p10(pmag); dphi=res_p9(pmag);} else if(theta_deg>=15 && theta_deg<25) {dp=res_p2(pmag); dtheta_deg=res_p10(pmag); dphi=res_p9(pmag);} else if(theta_deg>=25 && theta_deg<35) {dp=res_p3(pmag); dtheta_deg=res_p10(pmag); dphi=res_p9(pmag);} else if(theta_deg>=35 && theta_deg<45) {dp=res_p4(pmag); dtheta_deg=res_p11(pmag); dphi=res_p9(pmag);} else if(theta_deg>=45 && theta_deg<55) {dp=res_p4(pmag); dtheta_deg=res_p12(pmag); dphi=res_p9(pmag);} else if(theta_deg>=55) { dtheta_deg=res_p12(pmag); dphi=res_p9(pmag); if(pmag<2.0) dp=res_p6(theta_deg); else if(pmag>=2.0 && pmag<3.0) dp=res_p7(theta_deg); else if(pmag>=3.0) dp=res_p8(theta_deg); } dtheta = dtheta_deg*3.14159/180.0; dphi *=3.14159/180.0; //cerr << "Pre: dp/dtheta/dphi: " << dp << " " << dtheta << " " << dphi << endl; dp=dp*pmag/2.0; dtheta=dtheta/2.0; dphi=dphi/2.0; DMatrixDSym errMat(7); DMatrix sphErrMat(3,3); DMatrix transformMat(3,3); DMatrix transformMat_T(3,3); DMatrix cartErrMat(3,3); sphErrMat[0][0] = dp*dp; //sphErrMat[0][1] = dp*dtheta; //sphErrMat[0][2] = dp*dphi; //sphErrMat[1][0] = dtheta*dp; sphErrMat[1][1] = dtheta*dtheta; //sphErrMat[1][2] = dtheta*dphi; //sphErrMat[2][0] = dphi*dp; //sphErrMat[2][1] = dphi*dtheta; sphErrMat[2][2] = dphi*dphi; //cerr << "(0,1) pmag/theta/phi: " << pmag << " " << theta << " " << phi << endl; //cerr << "(0,1) pmag/cos(theta)/cos(phi): " << pmag << " " << cos(theta) << " " << cos(phi) << endl; transformMat[0][0] = sin(theta)*cos(phi); transformMat[1][0] = pmag*cos(theta)*cos(phi); transformMat[2][0] = -pmag*sin(theta)*sin(phi); transformMat[0][1] = sin(theta)*sin(phi); transformMat[1][1] = pmag*cos(theta)*sin(phi); transformMat[2][1] = -pmag*sin(theta)*cos(phi); transformMat[0][2] = cos(phi); transformMat[1][2] = pmag*sin(theta); transformMat[2][2] = 1; transformMat_T.Transpose(transformMat); cartErrMat = transformMat_T * sphErrMat * transformMat; /* cerr << "spherical: " << endl; for(int i=0;isetMass(0.0); trk->setMomentum(mom); trk->setErrorMatrix(errMat); } double DTrack_factory_THROWN::res_p1(double x) { // Return dpmag/pmag(theta) // 0=5.5768) { res = 0.16847; } return res; } double DTrack_factory_THROWN::res_p10(double x) { // Return dtheta/theta(p) // 0=4) { res=0.096163; } return res; } double DTrack_factory_THROWN::res_p11(double x) { // Return dtheta/theta(p) // 35=4) { res=0.1478; } return res; } double DTrack_factory_THROWN::res_p12(double x) { // Return dtheta/theta(p) // 45=4) { res=0.20749; } return res; }