src/MapsTrack.cc

Go to the documentation of this file.
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 //struct sensorHitPrinter :
00013 //public std::binary_function<MapsSensor*, MapsTrack::coord>, void> {
00014 //      void operator()(MapsSensor* s, MapsTrack::coord p) const {
00015 //              std::cout << *s;
00016 //              std::cout << "\tInput:\t" << p;
00017 //              MapsTrack::physXY place;
00018 //              s->convertHitToPhysical(p, place);
00019 //              std::cout << "\t--> " << place << "\n";
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 //and Y
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 //their meanX and Y
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         //loop over the supplied ids
00117         for (std::vector<MapsSensor*>::const_iterator it = sensors.begin(); it
00118                         != sensors.end(); it++) {
00119                 MapsSensor* sensorToCheck = *it;
00120                 //does the hit map contain it
00121                 if (myHits.count(sensorToCheck) == 0)
00122                         return sensorToCheck;
00123         }
00124 
00125         //all ids are contained in the map, so return null
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         //sum over i of 1 = N
00173         unsigned n(myHits.size());
00174         //sum over i of the z positions
00175         double sumZi(0);
00176         //and the z squareds
00177         double sumZiSq(0);
00178 
00179         //sum over x_i
00180         double sumXi(0);
00181         //sum over x_i * z_i
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                 //PRE-PHYSICAL XY
00188                 //std::pair<double, double> xy((*it).second);
00189                 //POST
00190                 //              std::pair<double, double> xy;
00191                 //              s->convertHitToPhysical((*it).second, xy);
00192                 std::pair<double, double> xy((*it).second);
00193                 //NEW: sensors now do their own alignment
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         //std::cout << "n:\t" << n << ", sumZi:\t" << sumZi << ", sumZiSq:\t"
00209         //              << sumZiSq << ", sumXi:\t" << sumXi << ", sumXiZi:\t" << sumXiZi
00210         //              << "\n";
00211         double detM(n * sumZiSq -sumZi * sumZi);
00212         double delta(1.0/detM);
00213         //std::cout << "detM:\t" << detM << "\n";
00214         double p0(delta * sumZiSq * sumXi -delta * sumZi * sumXiZi);
00215         double p1(-1.0 * delta * sumZi * sumXi + n * delta * sumXiZi);
00216         //std::cout << "\tp0:\t" << p0 << ", p1:\t" << p1 << "\n";
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                 //PRE-PHYSICAL XY
00229                 std::pair<double, double> xy((*it).second);
00230                 //POST
00231                 //std::pair<double, double> xy;
00232                 //s->convertHitToPhysical((*it).second, xy);
00233                 //std::pair<double, double> c = xy + s->getAlignment();
00234                 //NEW: Sensors now do their own alignments
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         //first check a hit exists for this sensor
00279         if (getGlobalHits().count(s) == 0) {
00280                 // no such hit exists
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         //what fraction should this difference be multiplied by to get to a
00293         //predicted x,y position?
00294         double zscale = s->zPosition()/(right->zPosition() - left->zPosition());
00295         //std::cout << "\tZScale:\t" << zscale << "\n";
00296         //what's the predicted coordinate of the third hit?
00297         MapsSensor::physXY pred(0, 0);
00298         pred.first = diff.first * zscale;
00299         pred.second = diff.second * zscale;
00300         //std::cout << "\tShift" << pred << "\n";
00301         MapsSensor::physXY lXY = globals.at(left);
00302         MapsSensor::physXY sXY = globals.at(s);
00303         pred = pred + lXY;
00304         //std::cout << "\tPred:" << pred <<"\n";
00305         MapsSensor::physXY resid = pred - sXY;
00306         return resid;
00307 }
00308 
00309 MapsSensor* MapsTrack::leftExtrapPoint(MapsSensor* s) const {
00310         //is it the left sensor?
00311         if (s == leftSensor()) {
00312                 //go through sensors, find the one whose distance between this sensor and itself is minimised
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         //is it the right sensor?
00333         if (s == rightSensor()) {
00334                 //go through sensors, find the one whose distance between this sensor and itself is minimised
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 //aligned output
00371 unsigned MapsTrack::getFourthHitResidual(const MapsTrack& threeHitTrack,
00372                 std::pair<double, double>& answer) {
00373 
00374         //If we don't have a fourth hit for comparison, tell these goons to go away
00375         if (getGlobalHits().size() == 3)
00376                 return 1;
00377 
00378         //aligned
00379         std::pair<double, double> fourthHitXY = getGlobalHits().at(myFourthSensor);
00380         answer = threeHitTrack.findXYPrediction(myFourthSensor->zPosition())
00381                                 - (fourthHitXY);
00382 //      answer = threeHitTrack.findXYPrediction(myFourthSensor->zPosition())
00383 //                      - (fourthHitXY + myFourthSensor->getAlignment());
00384         return 0;
00385 }
00386 
00387 const std::map<MapsSensor*, MapsTrack::physXY >& MapsTrack::getGlobalHits() const {
00388         //if (myGlobalHits.size() != myHits.size()) {
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 //this guy's aligned
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 

Generated on Wed Mar 19 17:47:58 2008 for MapsTracks by  doxygen 1.5.2