00001
00002
00003
00004
00005
00006
00007
00008 #include <vector>
00009 #include <set>
00010
00011
00012 #include "StEventTypes.h"
00013
00014
00015 #include "Line.hh"
00016 #include "Track.hh"
00017 #include "TopologyMap.hh"
00018 #include "StBeamBackMaker.h"
00019
00020 #define MAX_R_DISTANCE 5. // cm
00021 #define MAX_Z_DISTANCE 10. // cm
00022 #define MIN_TRACK_SEED_HITS 60
00023
00024 struct LessHit {
00025 bool operator()(const StHit* hit1, const StHit* hit2) const
00026 {
00027 return hit1->position().z() < hit2->position().z();
00028 }
00029 };
00030
00031 typedef multiset<StHit*, LessHit> HitSet;
00032 typedef HitSet::iterator HitSetIter;
00033
00034 struct LessTrack {
00035 bool operator()(const Track* track1, const Track* track2) const
00036 {
00037 return track1->size() < track2->size();
00038 }
00039 };
00040
00041 typedef multiset<Track*, LessTrack> TrackSet;
00042 typedef TrackSet::iterator TrackSetIter;
00043
00044 ClassImp(StBeamBackMaker)
00045
00046 Int_t StBeamBackMaker::Make()
00047 {
00048 info() << "Processing run=" << GetRunNumber()
00049 << ", event=" << GetEventNumber() << endm;
00050
00051 StEvent* event = (StEvent*)GetInputDS("StEvent");
00052 if (!event) {
00053 warning("No StEvent");
00054 return kStWarn;
00055 }
00056
00057 StTpcHitCollection* tpc = event->tpcHitCollection();
00058 if (!tpc) {
00059 info("No TPC hits");
00060 return kStOk;
00061 }
00062
00063 info() << tpc->numberOfHits() << " TPC hits in event" << endm;
00064
00065
00066
00067
00068
00069
00070
00071 HitSet hits;
00072 for (UInt_t sector = 0; sector < tpc->numberOfSectors(); ++sector) {
00073 for (UInt_t padrow = 0; padrow < tpc->sector(sector)->numberOfPadrows(); ++padrow) {
00074 for (UInt_t i = 0; i < tpc->sector(sector)->padrow(padrow)->hits().size(); ++i) {
00075 StHit* hit = tpc->sector(sector)->padrow(padrow)->hits()[i];
00076 if (!hit->trackReferenceCount()) {
00077 hits.insert(hit);
00078 }
00079 }
00080 }
00081 }
00082 info() << hits.size() << " unused TPC hits in event" << endm;
00083
00084
00085
00086
00087 info("Find track seeds");
00088
00089 Track* bufBeg = (Track*)malloc(sizeof(Track)*hits.size());
00090 Track* bufEnd = bufBeg;
00091 TrackSet tracks;
00092 while (!hits.empty()) {
00093 Track* track = bufEnd++;
00094 new (track) Track;
00095 StHit* hit = *hits.begin();
00096 track->push_back(hit);
00097 hits.erase(hits.begin());
00098
00099 double sumX = hit->position().x();
00100 double sumY = hit->position().y();
00101 double meanX = sumX;
00102 double meanY = sumY;
00103
00104 for (HitSetIter i = hits.begin(); i != hits.end();) {
00105 StHit* hit = *i;
00106 double dz = hit->position().z() - track->lastHit()->position().z();
00107 if (fabs(dz) > MAX_Z_DISTANCE) break;
00108 double dx = meanX - hit->position().x();
00109 double dy = meanY - hit->position().y();
00110 double dr = hypot(dx, dy);
00111 if (dr < MAX_R_DISTANCE) {
00112 track->push_back(hit);
00113 HitSetIter next = i;
00114 ++next;
00115 hits.erase(i);
00116 i = next;
00117
00118 sumX += hit->position().x();
00119 sumY += hit->position().y();
00120 meanX = sumX / track->size();
00121 meanY = sumY / track->size();
00122 }
00123 else {
00124 ++i;
00125 }
00126 }
00127 tracks.insert(track);
00128 }
00129 info() << tracks.size() << " track seeds found" << endm;
00130
00131
00132
00133
00134
00135 info() << "Removing track seeds with less than "
00136 << MIN_TRACK_SEED_HITS << " hits" << endm;
00137 for (TrackSetIter i = tracks.begin(); i != tracks.end();) {
00138 Track* track = *i;
00139 if (track->size() < MIN_TRACK_SEED_HITS) {
00140 for (Track::iterator j = track->begin(); j != track->end(); ++j) {
00141 StHit* hit = *j;
00142 hits.insert(hit);
00143 }
00144 TrackSetIter next = i;
00145 ++next;
00146 tracks.erase(i);
00147 i = next;
00148 }
00149 else {
00150 ++i;
00151 }
00152 }
00153 info() << tracks.size() << " track seeds left with " << MIN_TRACK_SEED_HITS << " hits or more" << endm;
00154
00155
00156
00157
00158
00159 info("Find linear tracks");
00160 vector<Track*> linearTracks;
00161 for (TrackSetIter i = tracks.begin(); i != tracks.end(); ++i) {
00162 Track* track = *i;
00163 if (track->fit() && track->ok()) {
00164
00165
00166
00167
00168
00169 for (HitSetIter j = hits.begin(); j != hits.end();) {
00170 StHit* hit = *j;
00171 if (track->accept(hit)) {
00172 track->push_back(hit);
00173
00174 nth_element(track->begin(), track->rbegin().base(), track->end(), LessHit());
00175 track->fit();
00176 HitSetIter next = j;
00177 ++next;
00178 hits.erase(j);
00179 j = next;
00180 }
00181 else {
00182 ++j;
00183 }
00184 }
00185 linearTracks.push_back(track);
00186 }
00187 }
00188 info() << linearTracks.size() << " linear tracks found" << endm;
00189
00190
00191
00192
00193
00194 info("Start merging tracks");
00195 for (unsigned int i = 0; i < linearTracks.size(); ++i) {
00196 if (!linearTracks[i]) continue;
00197 for (unsigned int j = i + 1; j < linearTracks.size(); ++j) {
00198 if (!linearTracks[j]) continue;
00199 if (linearTracks[i]->accept(linearTracks[j]->firstHit()) &&
00200 linearTracks[i]->accept(linearTracks[j]->lastHit())) {
00201 linearTracks[i]->merge(linearTracks[j]);
00202 linearTracks[j] = 0;
00203 }
00204 }
00205 }
00206
00207
00208
00209
00210 linearTracks.erase(remove(linearTracks.begin(), linearTracks.end(),
00211 (Track*)0), linearTracks.end());
00212 info() << linearTracks.size() << " merged tracks" << endm;
00213
00214
00215
00216
00217 info("Refit and remove outliers");
00218 for (unsigned int i = 0; i < linearTracks.size(); ++i) {
00219 Track* track = linearTracks[i];
00220 if (track->fit()) {
00221 for (Track::iterator j = track->begin(); j != track->end();) {
00222 StHit* hit = *j;
00223 if (track->accept(hit)) {
00224 ++j;
00225 }
00226 else {
00227 j = track->erase(j);
00228 hits.insert(hit);
00229 }
00230 }
00231 }
00232 }
00233 info() << hits.size() << " unused TPC hits" << endm;
00234
00235
00236
00237
00238 int nHits = 0;
00239 for (unsigned int i = 0; i < linearTracks.size(); ++i)
00240 nHits += linearTracks[i]->size();
00241 info() << nHits << " TPC hits in linear tracks" << endm;
00242
00243
00244
00245
00246
00247
00248
00249 info("Converting Track to StTrack");
00250 Int_t key = 0;
00251 for (unsigned int i = 0; i < event->trackNodes().size(); ++i) {
00252 Int_t key2 = event->trackNodes()[i]->track(global)->key();
00253 if (key < key2) key = key2;
00254 }
00255
00256 Int_t nStTrack = 0;
00257 for (unsigned int i = 0; i < linearTracks.size(); ++i) {
00258 if (pileup(linearTracks[i])) continue;
00259 StTrack* track = createStTrack(linearTracks[i]);
00260 StTrackNode* trackNode = new StTrackNode;
00261 track->setKey(++key);
00262 trackNode->addTrack(track);
00263 event->trackNodes().push_back(trackNode);
00264 event->trackDetectorInfo().push_back(track->detectorInfo());
00265 ++nStTrack;
00266 }
00267 info() << nStTrack << " StTrack saved" << endm;
00268
00269
00270
00271
00272 for (Track* track = bufBeg; track != bufEnd; ++track) track->~Track();
00273 free(bufBeg);
00274
00275 return kStOk;
00276 }
00277
00278 StTrack* StBeamBackMaker::createStTrack(Track* track)
00279 {
00280 StTrack* gTrack = new StGlobalTrack;
00281 gTrack->setLength(track->length());
00282 gTrack->setFlag(901);
00283
00284 StThreeVectorF origin(track->x0(), track->y0(), 0);
00285 StThreeVectorF momentum(track->dxdz(), track->dydz(), 1);
00286 Line line(origin, momentum);
00287 momentum.setMag(999);
00288 double dipAngle = atan2(1, hypot(track->dxdz(), track->dydz()));
00289 gTrack->setGeometry(new StHelixModel(-1,
00290 M_PI_2,
00291 0,
00292 dipAngle,
00293 line.perigee(track->firstHit()->position()),
00294 momentum,
00295 1));
00296 gTrack->setEncodedMethod(kLine2StepId);
00297
00298 StTrackGeometry* outerGeometry = gTrack->geometry()->copy();
00299 outerGeometry->setOrigin(line.perigee(track->lastHit()->position()));
00300 gTrack->setOuterGeometry(outerGeometry);
00301
00302
00303 StTrackDetectorInfo* detInfo = new StTrackDetectorInfo;
00304 detInfo->setFirstPoint(track->firstHit()->position());
00305 detInfo->setLastPoint(track->lastHit()->position());
00306 for (Track::iterator i = track->begin(); i != track->end(); ++i)
00307 detInfo->addHit(*i);
00308
00309 detInfo->setNumberOfPoints(track->size() < 256 ? track->size() : 255, kTpcId);
00310 gTrack->setDetectorInfo(detInfo);
00311
00312 StTrackFitTraits fitTraits;
00313
00314 fitTraits.setNumberOfFitPoints(track->size() < 256 ? track->size() : 255, kTpcId);
00315 gTrack->setFitTraits(fitTraits);
00316
00317 return gTrack;
00318 }
00319
00320 inline bool StBeamBackMaker::pileup(Track* track) const
00321 {
00322 TopologyMap topoMap(track);
00323 return (topoMap.nearEast() < 4 || topoMap.farEast() < 4 ||
00324 topoMap.nearWest() < 4 || topoMap.farWest() < 4);
00325 }
00326
00327 inline ostream& StBeamBackMaker::info(const Char_t* message)
00328 {
00329 if (message)
00330 return gMessMgr->Info(Form("%s: %s", GetName(), message));
00331 return gMessMgr->Info() << GetName() << ": ";
00332 }
00333
00334 inline ostream& StBeamBackMaker::warning(const Char_t* message)
00335 {
00336 if (message)
00337 return gMessMgr->Warning(Form("%s: %s", GetName(), message));
00338 return gMessMgr->Warning() << GetName() << ": ";
00339 }