00001 #include "MapsTrack.hh"
00002 #include <cmath>
00003 #include "MapsException.hh"
00004 #include "TMath.h"
00005 #include <algorithm>
00006 #include <functional>
00007
00008 MapsTrack::~MapsTrack() {
00009
00010 }
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 const std::map<MapsSensor*, MapsTrack::coord>& MapsTrack::getHits() {
00024 return myHits;
00025 }
00026
00027 void MapsTrack::setPixelPitch(const double& pitch) {
00028 myPixelPitch = pitch;
00029 }
00030
00031 void MapsTrack::setTrackError(const std::pair<double, double>& error) {
00032 myTrackError = error;
00033 }
00034
00035 void MapsTrack::setHits(std::map<MapsSensor*, MapsTrack::coord> hits) {
00036 myHits = hits;
00037 getGlobalHits();
00038 }
00039 double MapsTrack::sigmaX() const {
00040 double x(0);
00041 double x2(0);
00042 unsigned count(0);
00043 for (std::map<MapsSensor*, MapsTrack::physXY>::const_iterator it =
00044 getGlobalHits().begin(); it != getGlobalHits().end(); ++it) {
00045 const physXY& c = (*it).second;
00046 x += c.first;
00047 x2 += c.first * c.first;
00048 count++;
00049 }
00050 return sqrt(static_cast<double>(x2)/count - static_cast<double>(x*x)/(count
00051 *count));
00052 }
00053
00054 double MapsTrack::sigmaY() const {
00055 double y(0);
00056 double y2(0);
00057 unsigned count(0);
00058 for (std::map<MapsSensor*, physXY>::const_iterator it = getGlobalHits().begin(); it != getGlobalHits().end(); ++it) {
00059 const physXY& c = (*it).second;
00060 y += c.second;
00061 y2 += c.second * c.second;
00062 count++;
00063 }
00064 return sqrt(static_cast<double>(y2)/count - static_cast<double>(y*y)/(count
00065 *count));
00066 }
00067
00068 double MapsTrack::meanX() const {
00069 double x(0);
00070 unsigned count(0);
00071 for (std::map<MapsSensor*, physXY>::const_iterator it = getGlobalHits().begin(); it != getGlobalHits().end(); ++it) {
00072 const physXY& c = (*it).second;
00073 x += c.first;
00074 count++;
00075 }
00076 return static_cast<double>(x)/count;
00077 }
00078 double MapsTrack::meanY() const {
00079 double y(0);
00080 unsigned count(0);
00081 for (std::map<MapsSensor*, physXY>::const_iterator it = getGlobalHits().begin(); it != getGlobalHits().end(); ++it) {
00082 const physXY& c = (*it).second;
00083 y += c.second;
00084 count++;
00085 }
00086 return static_cast<double>(y)/count;
00087 }
00088
00089 MapsSensor* MapsTrack::fourthSensor() const {
00090 return myFourthSensor;
00091 }
00092 void MapsTrack::setFourthSensorThresh(const unsigned& fourthThresh) {
00093 myFourthThresh = fourthThresh;
00094 }
00095
00096 void MapsTrack::tellSensorsOfResiduals() {
00097 if (!myToldSensorsResids) {
00098 for (std::map<MapsSensor*, physXY>::const_iterator it = getGlobalHits().begin(); it != getGlobalHits().end(); it++) {
00099 std::pair<double, double> resid = simpleResidual((*it).first);
00100 ((*it).first)->setResidual(resid);
00101 }
00102 myToldSensorsResids = true;
00103 }
00104 }
00105
00106 void MapsTrack::tellSensorsOfResiduals(const MapsSensor* const requiredLeft,
00107 const MapsSensor* const requiredRight) {
00108 if (leftSensor() == requiredLeft && rightSensor() == requiredRight)
00109 tellSensorsOfResiduals();
00110 }
00111
00112 void MapsTrack::tellSensorsOfHits() {
00113 std::cout << __PRETTY_FUNCTION__ << ":\t Not yet implemented!\n";
00114 }
00115 MapsSensor* MapsTrack::missingSensor(std::vector<MapsSensor*> sensors) const {
00116
00117 for (std::vector<MapsSensor*>::const_iterator it = sensors.begin(); it
00118 != sensors.end(); it++) {
00119 MapsSensor* sensorToCheck = *it;
00120
00121 if (myHits.count(sensorToCheck) == 0)
00122 return sensorToCheck;
00123 }
00124
00125
00126 return 0;
00127 }
00128
00129 double MapsTrack::theta() const {
00130
00131 std::pair<double, double> p = fitParameters(0);
00132 std::pair<double, double> q = fitParameters(1);
00133 return acos(1.0/sqrt(pow(p.second, 2) + pow(q.second, 2) + 1));
00134
00135 }
00136
00137 MapsSensor* MapsTrack::leftSensor() const {
00138 double leftZ(0);
00139 MapsSensor* leftSensor = 0;
00140 for (std::map<MapsSensor*, coord>::const_iterator it = myHits.begin(); it
00141 != myHits.end(); it++) {
00142 MapsSensor* s = (*it).first;
00143 if (leftSensor == 0) {
00144 leftZ = s->zPosition();
00145 leftSensor = s;
00146 } else if (s->zPosition() < leftZ) {
00147 leftZ = s->zPosition();
00148 leftSensor = s;
00149 }
00150 }
00151 return leftSensor;
00152 }
00153
00154 MapsSensor* MapsTrack::rightSensor() const {
00155 double rightZ(0);
00156 MapsSensor* rightSensor = 0;
00157 for (std::map<MapsSensor*, coord>::const_iterator it = myHits.begin(); it
00158 != myHits.end(); it++) {
00159 MapsSensor* s = (*it).first;
00160 if (rightSensor == 0) {
00161 rightZ = s->zPosition();
00162 rightSensor = s;
00163 } else if (s->zPosition() > rightZ) {
00164 rightZ = s->zPosition();
00165 rightSensor = s;
00166 }
00167 }
00168 return rightSensor;
00169 }
00170
00171 std::pair<double, double> MapsTrack::fitParameters(const unsigned& dimension) const {
00172
00173 unsigned n(myHits.size());
00174
00175 double sumZi(0);
00176
00177 double sumZiSq(0);
00178
00179
00180 double sumXi(0);
00181
00182 double sumXiZi(0);
00183
00184 for (std::map<MapsSensor*, MapsTrack::physXY>::const_iterator it =
00185 getGlobalHits().begin(); it != getGlobalHits().end(); ++it) {
00186 MapsSensor* s = (*it).first;
00187
00188
00189
00190
00191
00192 std::pair<double, double> xy((*it).second);
00193
00194 std::pair<double, double> c = xy;
00195 sumZi += s->zPosition();
00196 sumZiSq += s->zPosition() * s->zPosition();
00197 if (dimension == 0) {
00198 sumXi += c.first;
00199 sumXiZi += c.first * s->zPosition();
00200 } else if (dimension == 1) {
00201 sumXi += c.second;
00202 sumXiZi += c.second * s->zPosition();
00203 } else {
00204 throw 0;
00205 }
00206 }
00207
00208
00209
00210
00211 double detM(n * sumZiSq -sumZi * sumZi);
00212 double delta(1.0/detM);
00213
00214 double p0(delta * sumZiSq * sumXi -delta * sumZi * sumXiZi);
00215 double p1(-1.0 * delta * sumZi * sumXi + n * delta * sumXiZi);
00216
00217 std::pair<double, double> answer(p0, p1);
00218
00219 return answer;
00220 }
00221
00222 double MapsTrack::chiSq(const unsigned& dimension) const {
00223 double chiSq(0);
00224 std::pair<double, double> ps = fitParameters(dimension);
00225 for (std::map<MapsSensor*, MapsTrack::physXY>::const_iterator it =
00226 getGlobalHits().begin(); it != getGlobalHits().end(); ++it) {
00227 MapsSensor* s = (*it).first;
00228
00229 std::pair<double, double> xy((*it).second);
00230
00231
00232
00233
00234
00235 std::pair<double, double> c = xy;
00236 if (dimension ==0) {
00237 chiSq += pow(c.first - (ps.first + s->zPosition()
00238 * ps.second), 2) / pow(myTrackError.first, 2);
00239 } else {
00240 chiSq += pow(c.second - (ps.first + s->zPosition()
00241 * ps.second), 2) / pow(myTrackError.second, 2);
00242 }
00243 }
00244 return chiSq;
00245 }
00246
00247 double MapsTrack::chiSqProb(const unsigned& dimension) const {
00248 Double_t theChiSq(chiSq(dimension));
00249 Int_t ndf(getGlobalHits().size() - 2);
00250 return TMath::Prob(theChiSq, ndf);
00251 }
00252
00253 std::ostream& MapsTrack::printCoords(std::ostream& s) const {
00254 for (std::map<MapsSensor*, MapsTrack::coord>::const_iterator it =
00255 myHits.begin(); it != myHits.end(); it++) {
00256 if((*it).first->phi() < 1.5)
00257 s << *((*it).first) << "\t: " << (*it).second << "\t--> [" << (*it).second << "], " << getGlobalHits().at(((*it).first)) << "\n";
00258 else {
00259 MapsTrack::coord offset(168, 168);
00260 s << *((*it).first) << "\t: " << (*it).second << "\t--> [" << offset - (*it).second << "], " << getGlobalHits().at(((*it).first)) << "\n";
00261 }
00262
00263 }
00264 return s;
00265 }
00266
00267 std::map<MapsSensor*, std::pair<double, double> > MapsTrack::allResiduals() {
00268 std::map<MapsSensor*, std::pair<double, double> > resids;
00269 for (std::map<MapsSensor*, physXY>::const_iterator it = getGlobalHits().begin(); it != getGlobalHits().end(); it++) {
00270 MapsSensor* s = (*it).first;
00271 resids[s] = simpleResidual(s);
00272 }
00273 return resids;
00274 }
00275
00276 std::pair<double, double> MapsTrack::simpleResidual(MapsSensor* s) const
00277 throw(MapsException) {
00278
00279 if (getGlobalHits().count(s) == 0) {
00280
00281 std::string desc(__PRETTY_FUNCTION__);
00282 desc.append(": Sensor doesn't exist!\n");
00283 MapsException me(desc.c_str());
00284 throw me;
00285 }
00286
00287 MapsSensor* left = leftExtrapPoint(s);
00288 MapsSensor* right = rightExtrapPoint(s);
00289 std::map<MapsSensor*, physXY> globals = getGlobalHits();
00290 MapsSensor::physXY diff = globals.at(right) - globals.at(left);
00291
00292
00293
00294 double zscale = s->zPosition()/(right->zPosition() - left->zPosition());
00295
00296
00297 MapsSensor::physXY pred(0, 0);
00298 pred.first = diff.first * zscale;
00299 pred.second = diff.second * zscale;
00300
00301 MapsSensor::physXY lXY = globals.at(left);
00302 MapsSensor::physXY sXY = globals.at(s);
00303 pred = pred + lXY;
00304
00305 MapsSensor::physXY resid = pred - sXY;
00306 return resid;
00307 }
00308
00309 MapsSensor* MapsTrack::leftExtrapPoint(MapsSensor* s) const {
00310
00311 if (s == leftSensor()) {
00312
00313 double separation(pow(2, sizeof(double))-1);
00314 MapsSensor* chosenSensor = 0;
00315 for (std::map<MapsSensor*, coord>::const_iterator it = myHits.begin(); it
00316 != myHits.end(); it++) {
00317 MapsSensor* compare = (*it).first;
00318 if (compare != s) {
00319 if (separation > compare->zPosition() - s->zPosition()) {
00320 separation = compare->zPosition() - s->zPosition();
00321 chosenSensor = compare;
00322 }
00323 }
00324 }
00325 return chosenSensor;
00326 } else {
00327 return leftSensor();
00328 }
00329 }
00330
00331 MapsSensor* MapsTrack::rightExtrapPoint(MapsSensor* s) const {
00332
00333 if (s == rightSensor()) {
00334
00335 double separation(pow(2, sizeof(double)));
00336 MapsSensor* chosenSensor = 0;
00337 for (std::map<MapsSensor*, coord>::const_iterator it = myHits.begin(); it
00338 != myHits.end(); it++) {
00339 MapsSensor* compare = (*it).first;
00340 if (compare != s) {
00341 if (separation > s->zPosition() -compare->zPosition()) {
00342 separation = s->zPosition() -compare->zPosition();
00343 chosenSensor = compare;
00344 }
00345 }
00346 }
00347 return chosenSensor;
00348 } else {
00349 return rightSensor();
00350 }
00351 }
00352
00353 void MapsTrack::make3HitTrack(MapsTrack& mt) {
00354 if (myHits.size() == 3) {
00355 mt.setHits(myHits);
00356 } else {
00357 std::map<MapsSensor*, coord> newHits(myHits);
00358 newHits.erase(myFourthSensor);
00359 mt.setHits(newHits);
00360 }
00361
00362 mt.setFourthSensorThresh(myFourthThresh);
00363 mt.setPixelPitch(myPixelPitch);
00364 mt.setTrackError(myTrackError);
00365 mt.myT = myT;
00366 mt.myFourthSensor = myFourthSensor;
00367 mt.myToldSensorsHits = myToldSensorsHits;
00368 mt.myToldSensorsResids = myToldSensorsResids;
00369 }
00370
00371 unsigned MapsTrack::getFourthHitResidual(const MapsTrack& threeHitTrack,
00372 std::pair<double, double>& answer) {
00373
00374
00375 if (getGlobalHits().size() == 3)
00376 return 1;
00377
00378
00379 std::pair<double, double> fourthHitXY = getGlobalHits().at(myFourthSensor);
00380 answer = threeHitTrack.findXYPrediction(myFourthSensor->zPosition())
00381 - (fourthHitXY);
00382
00383
00384 return 0;
00385 }
00386
00387 const std::map<MapsSensor*, MapsTrack::physXY >& MapsTrack::getGlobalHits() const {
00388
00389 for (std::map<MapsSensor*, MapsTrack::coord>::const_iterator it =
00390 myHits.begin(); it != myHits.end(); ++it) {
00391 MapsSensor* s= (*it).first;
00392 physXY xy;
00393 s->convertHitToPhysical((*it).second, xy);
00394 myGlobalHits[s] = xy;
00395 }
00396
00397 return myGlobalHits;
00398 }
00399
00400 void MapsTrack::eraseGlobalHits() {
00401 myGlobalHits.clear();
00402 }
00403
00404
00405 std::pair<double, double> MapsTrack::findXYPrediction(const double& zpos) const {
00406 std::pair<double, double> p = fitParameters(0);
00407 std::pair<double, double> q = fitParameters(1);
00408
00409 std::pair<double, double> pred;
00410 pred.first = (p.first + zpos * p.second);
00411 pred.second = (q.first + zpos * q.second);
00412 return pred;
00413 }
00414
00415 std::ostream& diagnose(std::ostream& s, const MapsTrack& mt) {
00416 s.precision(3);
00417 s << std::fixed;
00418 s.width(3);
00419 std::pair<double, double> phys;
00420 s << "Track at BX:\t" << mt.timeStamp() << ", hit pattern:\n";
00421 mt.printCoords(s);
00422
00423 s << "\t\tchi2X:\t" << mt.chiSq(0) << "\t chi2Y:\t" << mt.chiSq(1)
00424 << "\tp:\t" << mt.fitParameters(0) << "\tq:\t"
00425 << mt.fitParameters(1) << "\n";
00426
00427 s << "\t\tchi2ProbX:\t" << mt.chiSqProb(0) << "\t chi2ProbY:\t"
00428 << mt.chiSqProb(1) << "\n";
00429 s << "\t\ttheta:\t" << mt.theta() << "\tmeanX:\t" << mt.meanX()
00430 << "\tmeanY:\t" << mt.meanY() << "\n";
00431 s << "\t\tleftSensor:\t" << *(mt.leftSensor()) << "\trightSensor:\t"
00432 << *(mt.rightSensor()) << "\n";
00433 return s;
00434 }
00435 std::ostream& operator<<(std::ostream& s, const MapsTrack& mt) {
00436 return s << "Track at BX = " << mt.timeStamp() << ", meanX: " << mt.meanX()
00437 << ", meanY: " << mt.meanY() << ", fourth sens: "
00438 << *(mt.fourthSensor());
00439 }
00440