00001
00002
00003
00004
00005
00006
00007
00008 #include "StMuTrack.h"
00009 #include "StMuDebug.h"
00010 #include "StMuException.hh"
00011 #include "StEvent/StEventTypes.h"
00012 #include "StEvent/StTrackGeometry.h"
00013 #include "StEvent/StPrimaryVertex.h"
00014 #include "StEvent/StDcaGeometry.h"
00016 #include "StEvent/StBTofHit.h"
00017 #include "StEvent/StBTofPidTraits.h"
00018 #include "StarClassLibrary/SystemOfUnits.h"
00019 #include "StEvent/StTpcDedxPidAlgorithm.h"
00020 #include "StarClassLibrary/StThreeVectorD.hh"
00021 #include "StarClassLibrary/StPhysicalHelixD.hh"
00022 #include "StarClassLibrary/StParticleTypes.hh"
00023 #include "StEventUtilities/StuProbabilityPidAlgorithm.h"
00024 #include "StMuDSTMaker/COMMON/StMuPrimaryVertex.h"
00025 #include "StEmcUtil/projection/StEmcPosition.h"
00026 #include "StEmcUtil/geometry/StEmcGeom.h"
00027 #include "THelixTrack.h"
00028 #include "TMath.h"
00029 #include "TString.h"
00030 namespace {
00031 const StThreeVectorF gDummy(-999,-999,-999);
00032 }
00033
00034 StuProbabilityPidAlgorithm* StMuTrack::mProbabilityPidAlgorithm=0;
00035 double StMuTrack::mProbabilityPidCentrality=0;
00036
00037
00038
00039
00040 StMuTrack::StMuTrack(const StEvent* event, const StTrack* track, const StVertex *vertex, int index2Global, int index2RichSpectra, bool l3, TObjArray *vtxList) :
00041 mId(0), mType(0), mFlag(0), mFlagExtension(0), mIndex2Global(index2Global), mIndex2RichSpectra(index2RichSpectra), mNHits(0), mNHitsPoss(0), mNHitsDedx(0),mNHitsFit(0),
00042 mPidProbElectron(0), mPidProbPion(0),mPidProbKaon(0),mPidProbProton(0),
00043
00044 mdEdx(0.), mPt(0.), mEta(0.), mPhi(0.), mIndex2Cov(-1), mIdTruth(0), mQuality(0), mIdParentVx(0) {
00045
00046 const StGlobalTrack* globalTrack = dynamic_cast<const StGlobalTrack*>(track->node()->track(global));
00047
00048 mId = track->key();
00049 mType = track->type();
00050 mFlag = track->flag();
00051 mFlagExtension = track->flagExtension();
00052 mTopologyMap = track->topologyMap();
00053 mIdTruth = track->idTruth();
00054 mQuality = track->qaTruth();
00055 mIdParentVx = track->idParentVx();
00056
00057
00058
00059 static StTpcDedxPidAlgorithm PidAlgorithm;
00060 static StElectron* Electron = StElectron::instance();
00061 static StPionPlus* Pion = StPionPlus::instance();
00062 static StKaonPlus* Kaon = StKaonPlus::instance();
00063 static StProton* Proton = StProton::instance();
00064 const StParticleDefinition* pd = track->pidTraits(PidAlgorithm);
00065 if (pd) {
00066 mNSigmaElectron = pack2Int( fabsMin(PidAlgorithm.numberOfSigma(Electron),__SIGMA_SCALE__), __SIGMA_SCALE__ );
00067 mNSigmaPion = pack2Int( fabsMin(PidAlgorithm.numberOfSigma(Pion),__SIGMA_SCALE__), __SIGMA_SCALE__ );
00068 mNSigmaKaon = pack2Int( fabsMin(PidAlgorithm.numberOfSigma(Kaon),__SIGMA_SCALE__), __SIGMA_SCALE__ );
00069 mNSigmaProton = pack2Int( fabsMin(PidAlgorithm.numberOfSigma(Proton),__SIGMA_SCALE__), __SIGMA_SCALE__ );
00070 } else {
00071
00072
00073
00074 mNSigmaElectron = int(__NOVALUE__*__SIGMA_SCALE__);
00075 mNSigmaPion = int(__NOVALUE__*__SIGMA_SCALE__);
00076 mNSigmaKaon = int(__NOVALUE__*__SIGMA_SCALE__);
00077 mNSigmaProton = int(__NOVALUE__*__SIGMA_SCALE__);
00078 }
00079
00080
00081 if ( PidAlgorithm.traits() ) {
00082 mdEdx = PidAlgorithm.traits()->mean();
00083 mNHitsDedx = PidAlgorithm.traits()->numberOfPoints();
00084 }
00085
00086
00087 if ( track->detectorInfo() ) {
00088 mFirstPoint = track->detectorInfo()->firstPoint();
00089 mLastPoint = track->detectorInfo()->lastPoint();
00090 mNHits = track->detectorInfo()->numberOfPoints();
00091 }
00092
00093 mNHitsPoss = track->numberOfPossiblePoints();
00094
00095 int tpc_hits;
00096 mNHitsPossTpc=0;
00097 if (track->numberOfPossiblePoints(kTpcId)==track->numberOfPossiblePoints(kFtpcEastId)) {
00098
00099 if (track->topologyMap().hasHitInDetector(kTpcId))
00100 mNHitsPossTpc=track->numberOfPossiblePoints(kTpcId);
00101 else if (track->topologyMap().hasHitInDetector(kFtpcEastId))
00102 mNHitsPossTpc=(1 << 6) + track->numberOfPossiblePoints(kFtpcEastId);
00103 else if (track->topologyMap().hasHitInDetector(kFtpcWestId))
00104 mNHitsPossTpc=(2 << 6) + track->numberOfPossiblePoints(kFtpcWestId);
00105 } else {
00106
00107 if ( (tpc_hits=track->numberOfPossiblePoints(kTpcId)) )
00108 mNHitsPossTpc=tpc_hits;
00109 else if ( (tpc_hits=track->numberOfPossiblePoints(kFtpcEastId)) )
00110 mNHitsPossTpc=(1 << 6) + tpc_hits;
00111 else if ( (tpc_hits=track->numberOfPossiblePoints(kFtpcWestId)) )
00112 mNHitsPossTpc=(2 << 6) + tpc_hits;
00113 }
00114
00115 mNHitsPossInner=track->numberOfPossiblePoints(kSvtId) & 0x7;
00116 if (! mNHitsPossInner) mNHitsPossInner=track->numberOfPossiblePoints(kIstId) & 0x7;
00117 mNHitsPossInner|=(track->numberOfPossiblePoints(kSsdId) & 0x3) << 3;
00118 mNHitsPossInner|=(track->numberOfPossiblePoints(kPxlId) & 0x7) << 5;
00119
00120 mNHitsFit = track->fitTraits().numberOfFitPoints();
00121 mNHitsFitTpc=0;
00122 if (track->numberOfPossiblePoints(kTpcId)==track->numberOfPossiblePoints(kFtpcEastId)) {
00123
00124 if (track->topologyMap().hasHitInDetector(kTpcId))
00125 mNHitsFitTpc=track->fitTraits().numberOfFitPoints(kTpcId);
00126 else if (track->topologyMap().hasHitInDetector(kFtpcEastId))
00127 mNHitsFitTpc=(1 << 6) + track->fitTraits().numberOfFitPoints(kFtpcEastId);
00128 else if (track->topologyMap().hasHitInDetector(kFtpcWestId))
00129 mNHitsFitTpc=(2 << 6) + track->fitTraits().numberOfFitPoints(kFtpcWestId);
00130 } else {
00131
00132 if ( (tpc_hits=track->fitTraits().numberOfFitPoints(kTpcId)) )
00133 mNHitsFitTpc=tpc_hits;
00134 else if ( (tpc_hits=track->fitTraits().numberOfFitPoints(kFtpcEastId)) )
00135 mNHitsFitTpc=(1 << 6) + tpc_hits;
00136 else if ( (tpc_hits=track->fitTraits().numberOfFitPoints(kFtpcWestId)) )
00137 mNHitsFitTpc=(2 << 6) + tpc_hits;
00138 }
00139 mNHitsFitInner=track->fitTraits().numberOfFitPoints(kSvtId) & 0x7;
00140 if (! mNHitsFitInner) mNHitsFitInner=track->fitTraits().numberOfFitPoints(kIstId) & 0x7;
00141 mNHitsFitInner|=(track->fitTraits().numberOfFitPoints(kSsdId) & 0x3) << 3;
00142 mNHitsFitInner|=(track->fitTraits().numberOfFitPoints(kPxlId) & 0x7) << 5;
00143
00144 mChiSqXY = track->fitTraits().chi2(0);
00145 mChiSqZ = track->fitTraits().chi2(1);
00146
00147 if ( track->geometry() && track->geometry()->charge()) {
00148 mHelix = StMuHelix(track->geometry()->helix(),event->runInfo()->magneticField());
00149
00150 if (vertex) {
00151 mP = momentumAtPrimaryVertex(event,track,vertex);
00152 Int_t vtx_id=vtxList->IndexOf(vertex);
00153 if (vtx_id >= 0) {
00154 mVertexIndex=vtx_id;
00155 }
00156 else {
00157 gMessMgr->Warning() << "Track does not point to a primary vertex" << endm;
00158 mVertexIndex = -1;
00159 mDCA = StThreeVectorF(-999,-999,-999);
00160 mDCAGlobal = StThreeVectorF(-999,-999,-999);
00161 }
00162 mDCA = dca(track, vertex);
00163 if (globalTrack) {
00164 if (globalTrack->dcaGeometry()) {
00165 const StDcaGeometry *dcaGeometry = globalTrack->dcaGeometry();
00166 const StThreeVectorF &pvert = vertex->position();
00167 Double_t vtx[3] = {pvert[0],pvert[1],pvert[2]};
00168 THelixTrack thelix = dcaGeometry->thelix();
00169 thelix.Move(thelix.Path(vtx));
00170 const Double_t *pos = thelix.Pos();
00171 const Double_t *mom = thelix.Dir();
00172 mDCAGlobal = StThreeVectorF(pos[0],pos[1],pos[2]) - vertex->position();
00173 if (track->type() == global) {
00174 mDCA = mDCAGlobal;
00175 mP = StThreeVectorF(mom[0],mom[1],mom[2]);
00176 mP *= dcaGeometry->momentum().mag();
00177 }
00178 }
00179 else {
00180 mDCAGlobal = dca(globalTrack, vertex);
00181 }
00182 }
00183 else {
00184 mDCAGlobal = StThreeVectorF(-999,-999,-999);
00185 }
00186
00187 mPt = mP.perp();
00188 mPhi = mP.phi();
00189 mEta = mP.pseudoRapidity();
00190
00191 if (!l3) {
00192 int charge = track->geometry()->charge();
00193
00194 mProbabilityPidAlgorithm->processPIDAsFunction(mProbabilityPidCentrality, mDCA.mag(), charge, mP.mag()/charge, mEta, mNHitsDedx, mdEdx);
00195 mPidProbElectron= pack2UnsignedShort( (charge>0) ? mProbabilityPidAlgorithm->beingPositronProb() : mProbabilityPidAlgorithm->beingElectronProb(), __PROB_SCALE__) ;
00196 mPidProbPion= pack2UnsignedShort( (charge>0) ? mProbabilityPidAlgorithm->beingPionPlusProb() : mProbabilityPidAlgorithm->beingPionMinusProb(), __PROB_SCALE__);
00197 mPidProbKaon= pack2UnsignedShort( (charge>0) ? mProbabilityPidAlgorithm->beingKaonPlusProb() : mProbabilityPidAlgorithm->beingKaonMinusProb(), __PROB_SCALE__);
00198 mPidProbProton= pack2UnsignedShort( (charge>0) ? mProbabilityPidAlgorithm->beingProtonProb() : mProbabilityPidAlgorithm->beingAntiProtonProb(), __PROB_SCALE__);
00199 }
00200 }
00201 else {
00202 mVertexIndex = -1;
00203 mDCA = StThreeVectorF(-999,-999,-999);
00204 mDCAGlobal = StThreeVectorF(-999,-999,-999);
00205 if (globalTrack) {
00206 if (globalTrack->dcaGeometry()) {
00207 const StDcaGeometry *dcaGeometry = globalTrack->dcaGeometry();
00208 THelixTrack thelix = dcaGeometry->thelix();
00209 const Double_t *mom = thelix.Dir();
00210 if (track->type() == global) {
00211 mP = StThreeVectorF(mom[0],mom[1],mom[2]);
00212 mP *= dcaGeometry->momentum().mag();
00213 }
00214 }
00215 }
00216 mPt = mP.perp();
00217 mPhi = mP.phi();
00218 mEta = mP.pseudoRapidity();
00219 }
00220 }
00221 fillMuProbPidTraits(event,track);
00223 mIndex2BTofHit = -1;
00224 fillMuBTofPidTraits(track);
00225
00226 if ( track->outerGeometry() )
00227 mOuterHelix = StMuHelix(track->outerGeometry()->helix(),event->runInfo()->magneticField());
00228 }
00229
00230 unsigned short StMuTrack::nHitsPoss() const {
00231
00232 if (mNHitsPossTpc==255 && type()==primary)
00233 return mNHitsPoss+1;
00234
00235 return mNHitsPoss;
00236 }
00237
00238 unsigned short StMuTrack::nHitsPoss(StDetectorId det) const {
00239
00240
00241 if (mNHitsPossTpc==255) {
00242 if (det==kTpcId || det==kFtpcEastId || det==kFtpcWestId)
00243 return mTopologyMap.hasHitInDetector(det)*mNHitsPoss;
00244 else
00245 return 0;
00246 }
00247
00248
00249 switch (det) {
00250 case kTpcId:
00251 return ((mNHitsPossTpc & 0xC0)==0)*mNHitsPossTpc;
00252 break;
00253 case kFtpcEastId:
00254 return ((mNHitsPossTpc & 0xC0)==0x40)*(mNHitsPossTpc & 0x3F);
00255 break;
00256 case kFtpcWestId:
00257 return ((mNHitsPossTpc & 0xC0)==0x80)*(mNHitsPossTpc & 0x3F);
00258 break;
00259 case kSvtId:
00260 case kIstId:
00261 return (mNHitsPossInner & 0x7);
00262 break;
00263 case kSsdId:
00264 return ((mNHitsPossInner >> 3) & 0x3);
00265 break;
00266 case kPxlId:
00267 return ((mNHitsPossInner >> 5) & 0x7);
00268 break;
00269 default:
00270 return 0;
00271 }
00272
00273 }
00274
00275 unsigned short StMuTrack::nHitsFit(StDetectorId det) const {
00276
00277 if (mNHitsFitTpc==255) {
00278 if (det==kTpcId || det==kFtpcEastId || det==kFtpcWestId)
00279 return mTopologyMap.hasHitInDetector(det)*mNHitsFit;
00280 else
00281 return 0;
00282 }
00283
00284
00285 switch (det) {
00286 case kTpcId:
00287 return ((mNHitsFitTpc & 0xC0)==0)*mNHitsFitTpc;
00288 break;
00289 case kFtpcEastId:
00290 return ((mNHitsFitTpc & 0xC0)==0x40)*(mNHitsFitTpc & 0x3F);
00291 break;
00292 case kFtpcWestId:
00293 return ((mNHitsFitTpc & 0xC0)==0x80)*(mNHitsFitTpc & 0x3F);
00294 break;
00295 case kSvtId:
00296 case kIstId:
00297 return (mNHitsFitInner & 0x7);
00298 break;
00299 case kSsdId:
00300 return ((mNHitsFitInner >> 3) & 0x3);
00301 break;
00302 case kPxlId:
00303 return ((mNHitsFitInner >> 5) & 0x7);
00304 break;
00305 default:
00306 return 0;
00307 }
00308 }
00309
00310 Float_t StMuTrack::dcaD(Int_t vtx_id) const {
00311 if ((vtx_id == -1 && mVertexIndex == StMuDst::currentVertexIndex()) ||
00312 vtx_id == mVertexIndex) {
00313 StThreeVectorF dir;
00314 if (mType == global)
00315 dir = mP;
00316 else if (globalTrack())
00317 dir = globalTrack()->p();
00318 else
00319 return -999;
00320 if (dir.mag() == 0)
00321 return -999;
00322 dir /= dir.mag();
00323 Float_t cosl = dir.perp();
00324 return -dir[1]/cosl * mDCAGlobal[0] + dir[0]/cosl * mDCAGlobal[1];
00325 }
00326 else return -999;
00327 }
00328
00329 Float_t StMuTrack::dcaZ(Int_t vtx_id) const {
00330 if ((vtx_id == -1 && mVertexIndex == StMuDst::currentVertexIndex()) ||
00331 vtx_id == mVertexIndex) {
00332 return mDCAGlobal.z();
00333 }
00334 else return -999;
00335 }
00336
00337 StThreeVectorF StMuTrack::dca(Int_t vtx_id) const {
00338 if (vtx_id == -1)
00339 vtx_id = StMuDst::currentVertexIndex();
00340 if (vtx_id==mVertexIndex)
00341 return mDCA;
00342 else if (mVertexIndex == -1)
00343 return gDummy;
00344 if(((StMuPrimaryVertex*)StMuDst::array(muPrimaryVertex)->UncheckedAt(vtx_id)))
00345 return dca(((StMuPrimaryVertex*)StMuDst::array(muPrimaryVertex)->UncheckedAt(vtx_id))->position());
00346 else return gDummy;
00347 }
00348
00349 StThreeVectorF StMuTrack::dcaGlobal(Int_t vtx_id) const {
00350 if (vtx_id == -1)
00351 vtx_id = StMuDst::currentVertexIndex();
00352 if (vtx_id==mVertexIndex) {
00353 return mDCAGlobal;
00354 }
00355 else if (mVertexIndex == -1) {
00356 return gDummy;
00357 }
00358
00359 const StMuTrack *gTrack = (mType == global) ? this : globalTrack();
00360
00361 if (gTrack && ((StMuPrimaryVertex*)StMuDst::array(muPrimaryVertex)->UncheckedAt(vtx_id))){
00362 return gTrack->dca(((StMuPrimaryVertex*)StMuDst::array(muPrimaryVertex)->UncheckedAt(vtx_id))->position());
00363 }
00364 else {
00365 return gDummy;
00366 }
00367 }
00368
00369 StThreeVectorF StMuTrack::dca(const StThreeVectorF &pos) const {
00370 const StPhysicalHelixD &hlx = helix();
00371 double pathlength = hlx.pathLength(pos, false);
00372 return hlx.at(pathlength)-pos;
00373 }
00374
00375 StThreeVectorD StMuTrack::dca(const StTrack* track, const StVertex *vertex) const{
00376 double pathlength = track->geometry()->helix().pathLength( vertex->position(), false );
00377 return track->geometry()->helix().at(pathlength)-vertex->position();
00378 }
00379
00380 StThreeVectorD StMuTrack::momentumAtPrimaryVertex(const StEvent* event, const StTrack* track, const StVertex *vertex) const{
00381 double pathlength = track->geometry()->helix().pathLength( vertex->position() );
00382 return track->geometry()->helix().momentumAt(pathlength,event->runInfo()->magneticField()*kilogauss);
00383 }
00384
00385 StPhysicalHelixD StMuTrack::helix() const
00386 {
00387 return StPhysicalHelixD(mHelix.p(),mHelix.origin(), mHelix.b()*kilogauss, mHelix.q());
00388 }
00389
00390 StPhysicalHelixD StMuTrack::outerHelix() const {
00391 return StPhysicalHelixD(mOuterHelix.p(),mOuterHelix.origin(), mOuterHelix.b()*kilogauss, mOuterHelix.q());
00392 }
00393
00394 double StMuTrack::length() const {
00395 return fabs( helix().pathLength(StThreeVectorD(mLastPoint)) ); }
00396 double StMuTrack::lengthMeasured() const {
00397 return fabs( helix().pathLength(StThreeVectorD(mLastPoint)) - helix().pathLength(StThreeVectorD(mFirstPoint)) ); }
00398
00399 int StMuTrack::bad() const
00400 {
00401 if (mFlag <= 0 ) return 10;
00402 if (mHelix.bad()) return 20;
00403 if (mOuterHelix.bad()) return 30;
00404 return 0;
00405 }
00406 #include "StEvent/StProbPidTraits.h"
00407 void StMuTrack::fillMuProbPidTraits(const StEvent* e, const StTrack* t) {
00408
00409 StPtrVecTrackPidTraits traits = t->pidTraits(kTpcId);
00410
00411 StDedxPidTraits* dedxPidTraits =0;
00412 unsigned int size = traits.size();
00413
00414 if (StMuDebug::level()>=3) {
00415 cout << " dedxPidTraits->method() ";
00416 }
00417 for (unsigned int i = 0; i < size; i++) {
00418 if ( !(dedxPidTraits=dynamic_cast<StDedxPidTraits*>(traits[i])) ) continue;
00419 if (StMuDebug::level()>=3) {
00420 cout << " " << dedxPidTraits->method();
00421 }
00422 if (dedxPidTraits->method() == kTruncatedMeanIdentifier) {
00423 mProbPidTraits.setdEdxTruncated( dedxPidTraits->mean() );
00424 mProbPidTraits.setdEdxErrorTruncated( dedxPidTraits->errorOnMean() );
00425 mProbPidTraits.setLog2dX( dedxPidTraits->log2dX() );
00426 }
00427 if (dedxPidTraits->method() == kLikelihoodFitIdentifier) {
00428 mProbPidTraits.setdEdxFit( dedxPidTraits->mean() );
00429 mProbPidTraits.setdEdxErrorFit( dedxPidTraits->errorOnMean() );
00430 mProbPidTraits.setdEdxTrackLength( dedxPidTraits->length() );
00431 mProbPidTraits.setLog2dX( dedxPidTraits->log2dX() );
00432 }
00433 }
00434 if (StMuDebug::level()>=3) {
00435 cout << endl;
00436 }
00437
00438
00439 StProbPidTraits* probPidTraits =0;
00440 size = traits.size();
00441 for (unsigned int i = 0; i < size; i++) {
00442 if ( (probPidTraits=dynamic_cast<StProbPidTraits*>(traits[i])) ) {
00443 for (int i=0; i<mProbPidTraits.numberOfParticles(); i++) mProbPidTraits.setProbability(i,probPidTraits->GetProbability(i));
00444 mProbPidTraits.setNdf(probPidTraits->GetNDF());
00445 }
00446 }
00447
00448 }
00449
00450 void StMuTrack::fillMuBTofPidTraits(const StTrack* t) {
00451 StBTofPidTraits* btofPidTraits = 0;
00452 StPtrVecTrackPidTraits traits = t->pidTraits(kTofId);
00453 unsigned int size = traits.size();
00454 for (unsigned int i = 0; i < size; i++) {
00455 if ( (btofPidTraits=dynamic_cast<StBTofPidTraits*>(traits[i])) ) {
00456 mBTofPidTraits.setBTofPidTraits(btofPidTraits);
00457 }
00458 }
00459 }
00460 #if 0
00461 void StMuTrack::Print(Option_t *option) const {
00462
00463
00464
00465
00466
00467
00468
00469 if (mType == global)
00470 cout << "Global ";
00471 else if (mType == primary)
00472 cout << "Primary ";
00473 else
00474 cout << "Other type ";
00475 cout << "track, id " << mId << ", flag " << mFlag << " (>0 is OK)" << endl;
00476
00477 if (mVertexIndex != 0)
00478 cout << "Not assigned to primary vertex ( vertex Index " << mVertexIndex << " )" << endl;
00479
00480 cout << "momentum " << mP << endl;
00481 cout << "eta " << mEta << ", phi " << mPhi << ", pt " << mPt << endl;
00482 cout << "DCA " << mDCA << endl;
00483 cout << "\t radial " << dcaD() << ", z " << dcaZ() << endl;
00484 cout << "global DCA " << mDCAGlobal << endl;
00485 cout << "Total hits: " << nHits() << ", fitted " << nHitsFit()
00486 << "\t ( TPC "
00487 << nHitsFit(kTpcId) << ", FTPC "
00488 << nHitsFit(kFtpcEastId) + nHitsFit(kFtpcWestId) << ", SVT "
00489 << nHitsFit(kSvtId) << ", SSD "
00490 << nHitsFit(kSsdId) << " ) " << endl;
00491
00492 cout << "Possible points: " << nHitsPoss() << " \t( TPC "
00493 << nHitsPoss(kTpcId) << ", FTPC "
00494 << nHitsPoss(kFtpcEastId) + nHitsPoss(kFtpcWestId) << ", SVT "
00495 << nHitsPoss(kSvtId) << ", SSD "
00496 << nHitsPoss(kSsdId) << " ) " << endl;
00497
00498 cout << "\t first point " << mFirstPoint << endl;
00499 cout << "\t last point " << mLastPoint << endl;
00500
00501
00502 }
00503 #endif
00504 ostream& operator<<(ostream& os, const StMuTrack& v) {
00505 if (v.type() == global) os << "Gl ";
00506 else if (v.type() == primary) os << "Pr ";
00507 else os << " ";
00508 os << Form("id:%5i fl:%5i vx:%3i p:%8.3f %8.3f %8.3f",v.id(),v.flag(),v.vertexIndex(), v.p().x(), v.p().y(), v.p().z());
00509 os << Form(" q:%2i eta:%6.3f phi:%6.3f pT: %6.3f",v.charge(),v.eta(),v.phi(),v.pt());
00510 os << Form(" DCA:%6.3f %6.3f %6.3f",v.dca().x(),v.dca().y(),v.dca().z());
00511 os << Form(" Total hits:%2i fitted:%2i poss:%2i",v.nHits(),v.nHitsFit(),v.nHitsPoss());
00512 os << Form(" Points F: %6.3f %6.3f %6.3f L: %6.3f %6.3f %6.3f",
00513 v.firstPoint().x(),v.firstPoint().y(),v.firstPoint().z(),
00514 v.lastPoint().x(),v.lastPoint().y(),v.lastPoint().z());
00515 os << Form(" idT %4i qa %2i",v.idTruth(), v.qaTruth());
00516 return os;
00517 }
00518
00519 void StMuTrack::Print(Option_t *option) const {cout << *this << endl;}
00520
00521 const StMuTrack* StMuTrack::primaryTrack() const {
00522
00523 if(mType==1) return this;
00524 const StMuTrack *prim = 0;
00525
00526
00527
00528
00529 if(mIndex2Global==-1){
00530 int nVer = StMuDst::numberOfPrimaryVertices();
00531 StMuDst::fixTrackIndicesG(nVer);
00532 }
00533 if(mIndex2Global < 0 ) return prim;
00534
00535 if(StMuDst::numberOfPrimaryVertices()==0) return StMuDst::primaryTracks(mIndex2Global);
00536 int curVer = StMuDst::currentVertexIndex();
00537 StMuDst::setVertexIndex(mVertexIndex);
00538 prim = StMuDst::primaryTracks(mIndex2Global);
00539 StMuDst::setVertexIndex(curVer);
00540 return prim;
00541 }
00542
00543 int StMuTrack::vertexIndex() const {
00544
00545
00546 if (StMuDst::numberOfPrimaryVertices()==0){
00547 if(!(fabs(StMuDst::event()->primaryVertexPosition().x()) < 1.e-5 && fabs(StMuDst::event()->primaryVertexPosition().y()) < 1.e-5 && fabs(StMuDst::event()->primaryVertexPosition().z()) < 1.e-5)){
00548 if(primaryTrack()!=0) return 0;
00549 }
00550 else return -1;
00551 }
00552 if(this->type()==1) return mVertexIndex;
00553 if(primaryTrack()!=0) {
00554 int index = primaryTrack()->vertexIndex();
00555 return index;
00556 }
00557 else return -1;
00558 }
00559
00560 TArrayI StMuTrack::getTower(bool useExitRadius,int det) const{
00561
00562
00563 TArrayI tower(4);
00564 tower[0] = -10;
00565 tower[1] = -10;
00566 tower[2] = -10;
00567 tower[3] = -10;
00568
00569 StThreeVectorD momentum,position;
00570 Double_t radius;
00571
00572 StEmcGeom* mEmcGeom = StEmcGeom::instance("bemc");
00573 StEmcGeom* mSmdEGeom= StEmcGeom::instance("bsmde");
00574 StEmcGeom* mSmdPGeom= StEmcGeom::instance("bsmdp");
00575
00576 if(det==1) radius = mEmcGeom->Radius();
00577 if(det==2) radius = mEmcGeom->Radius();
00578 if(det==3) radius = mSmdEGeom->Radius();
00579 if(det==4) radius = mSmdPGeom->Radius();
00580
00581 StEventSummary& evtSummary = StMuDst::event()->eventSummary();
00582 Double_t mField = evtSummary.magneticField()/10;
00583
00584
00585 if(useExitRadius) radius += 30.0;
00586
00587 StEmcPosition mEmcPosition;
00588 bool goodProjection;
00589 if(this) goodProjection = mEmcPosition.trackOnEmc(&position,&momentum,this,mField,radius);
00590 else return tower;
00591 if(goodProjection){
00592 int m,e,s,id=0;
00593 float eta=position.pseudoRapidity();
00594 float phi=position.phi();
00595 if(det==1){
00596 mEmcGeom->getBin(phi,eta,m,e,s);
00597
00598 if(mEmcGeom->getId(m,e,s,id)==0){
00599 tower[0] = m;
00600 tower[1] = e;
00601 tower[2] = s;
00602 tower[3] = id;
00603 }
00604 }
00605 else if(det==3){
00606 int check=mSmdEGeom->getBin(phi,eta,m,e,s);
00607 if(!check){
00608 s = abs(s);
00609 if(mSmdEGeom->getId(m,e,s,id)==0){
00610 tower[0] = m;
00611 tower[1] = e;
00612 tower[2] = s;
00613 tower[3] = id; }
00614 }
00615 }
00616 else if(det==4){
00617 int check=mSmdPGeom->getBin(phi,eta,m,e,s);
00618 s = abs(s);
00619 if(!check){
00620 if(mSmdPGeom->getId(m,e,s,id)==0){
00621 tower[0] = m;
00622 tower[1] = e;
00623 tower[2] = s;
00624 tower[3] = s; }
00625 }
00626 }
00627 }
00628 return tower;
00629 }
00630
00631 double StMuTrack::energyBEMC() const {
00632
00633 double hitEnergy;
00634 TArrayI tower = getTower();
00635 unsigned int iMod = tower[0];
00636 unsigned int iEta = tower[1];
00637 int iSub = tower[2];
00638 if(iMod < 1 ||iMod > 120) return -100.0;
00639
00640 if (StMuDst::emcCollection()) {
00641 StEmcDetector *bemcDet = StMuDst::emcCollection()->detector(kBarrelEmcTowerId);
00642 StEmcModule *mod = bemcDet->module(iMod);
00643 StSPtrVecEmcRawHit& hits = mod->hits();
00644 for(unsigned int i=0; i<hits.size();i++){
00645 if(hits[i]){
00646 if((hits[i]->eta() == iEta) && (hits[i]->sub() == iSub)) {
00647 hitEnergy = hits[i]->energy();
00648 if(hitEnergy > 0) return hitEnergy;
00649 else return -100.0;
00650 }
00651 }
00652 }
00653 }
00654 return -100.0;
00655 }
00656
00657 bool StMuTrack::matchBEMC() const {
00658 double mEmcThres = 0.15;
00659 if (energyBEMC() > mEmcThres) return true;
00660 return false;
00661 }
00662
00663 ClassImp(StMuTrack)
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822