inc/MapsSensor.hh

Go to the documentation of this file.
00001 #ifndef MAPSSENSOR_HH_
00002 #define MAPSSENSOR_HH_
00003 
00004 #include <vector>
00005 #include <map>
00006 #include <algorithm>
00007 #include <functional>
00008 
00009 #include "TH1F.h"
00010 #include "TH2F.h"
00011 
00012 #include "ToString.h"
00013 #include "Operators.h"
00014 #include "MapsException.hh"
00015 
00016 /** MapsSensor.hh
00017  * 
00018  * Jamie Ballin, Imperial College London
00019  *              February 2008
00020  * 
00021  * 
00022  * A MapsSensor object knows its id, position in z, its clockwise angle of rotation 
00023  * relative to a world system, and its alignment relative to the world system. 
00024  * The sign convention of alignments is equal to that found from the sensor's residuals.
00025  * i.e. positive residual => set positive alignment.
00026  * 
00027  * Sensors should be told when they confirm or deny a hit in a track by calling the
00028  * appropriate methods.
00029  * 
00030  * Description of global geometry: physical coordiates (as opposed to pixel coordinates)
00031  * enter and leave this class in a global coordinate basis UNLESS otherwise specified by the
00032  * member method. On receipt of a global physical coordinate, this class will subtract its 
00033  * alignment and then rotate the coordinate by -1.0 * phi. Hits leaving this class are rotated
00034  * by phi, and then have the alignment added before being returned. 
00035  * 
00036  */
00037 class MapsSensor {
00038 public:
00039 
00040         typedef std::pair<int, int> coord;
00041 
00042         typedef std::pair<double, double> physXY;
00043 
00044         /**
00045          * MapsSensor constructors
00046          */
00047         MapsSensor(unsigned id, double zpos, double phi = 0) :
00048                 myId(id), myPosition(zpos), myPhi(phi), myAlignment(0, 0) {
00049         }
00050         ;
00051 
00052         MapsSensor(unsigned id, double zpos, physXY alignment, double phi = 0) :
00053                 myId(id), myPosition(zpos), myPhi(phi), myAlignment(alignment) {
00054 
00055         }
00056         ;
00057 
00058         MapsSensor::physXY getAlignment() const;
00059 
00060         /**
00061          * All units in mm please.
00062          */
00063         void setAlignment(MapsSensor::physXY alignment);
00064 
00065         /** 
00066          * Clockwise angle relative to world system, in radians.
00067          */
00068         inline void setPhi(const double phi) {
00069                 myPhi = phi;
00070         }
00071 
00072         /**
00073          * z position in mm
00074          */
00075         inline void setZPosition(const double zpos) {
00076                 myPosition = zpos;
00077         }
00078 
00079         /**
00080          * Returns the sensor id
00081          */
00082         inline unsigned id() {
00083                 return myId;
00084         }
00085         ;
00086 
00087         /** 
00088          * Returns the z position of this sensor
00089          */
00090         inline double zPosition() const {
00091                 return myPosition;
00092         }
00093         ;
00094 
00095         /** 
00096          * Returns the global polar angle of the sensor
00097          */
00098         inline double phi() {
00099                 return myPhi;
00100         }
00101         ;
00102 
00103         virtual ~MapsSensor();
00104 
00105         /** 
00106          * Call this when the sensor should confirm a track
00107          */
00108         void registerTrackConfirm(unsigned threshold, coord place, unsigned bx);
00109 
00110         /** 
00111          * Call this when the sensor should confirm a track
00112          */
00113         void registerTrackConfirm(unsigned threshold, coord place, unsigned bx,
00114                         physXY fourthHitResid);
00115 
00116         /**
00117          * Call this when it apparently misses a hit, with the predicted pixel coordinate
00118          */
00119         void registerTrackMiss(unsigned threshold, coord predicted, unsigned bx);
00120 
00121         /**
00122          * Call when the sensor misses a hit, with the predicted physical coordinate
00123          */
00124         void registerTrackMiss(unsigned threshold, physXY predicted, unsigned bx);
00125 
00126         /** 
00127          * A general purpose hit storage mechanism, not currently in use.
00128          */
00129         void registerGeneralHit(unsigned threshold, coord place, unsigned bx);
00130 
00131         /**
00132          * An xy plot of where inefficiencies were found using predicted hits
00133          */
00134         void getInefficiencyXYPlot(TH2F& plot, bool physicalXY = false);
00135 
00136         /** 
00137          * An xy plot of where the sensor was efficient
00138          */
00139         void getEfficiencyXYPlot(TH2F& plot);
00140 
00141         /**
00142          * Plots the difference between the extrapolated 3 hit track's position with the fourth
00143          * sensor, and the actual hit in the fourth sensor when this fourth sensor was judged efficient.
00144          */
00145         void getFourthHitResidualPlot(TH2F& plot);
00146 
00147         /**
00148          * Adds a residual to the list (a residual = predicted hit - actual hit)
00149          */
00150         void setResidual(physXY resid);
00151 
00152         /**
00153          * Efficiency as a function of bunch crossing.
00154          */
00155         void getEfficiencyTimestamps(TH1F& plot);
00156 
00157         /**
00158          * Inefficiency as a function of bunch crossing.
00159          */
00160         void getInefficiencyTimestamps(TH1F& plot);
00161 
00162         /**
00163          * Returns the efficiency, optionally excluding shapers or samplers.
00164          */
00165         double getEfficiency(unsigned threshold, bool withShapers = true,
00166                         bool withSamplers = true);
00167 
00168         /**
00169          * Returns the efficiency, optionally excluding shapers or samplers.
00170          */
00171         void getEfficiencyCurve(TH1F&, int bins, int low, int high,
00172                         bool withShapers = true, bool withSamplers = true);
00173 
00174         /**
00175          * Plots the efficiency by pixel group. If the threshold is not specified,
00176          * a summation over all thresholds is given. Otherwise, only selected thresholds
00177          * are presented.
00178          */
00179         void getEfficiencyByGroup(TH2F&, unsigned threshold = 0);
00180 
00181         /**
00182          * Plots the resdiuals as a function of local physical coordindates
00183          */
00184         void getResidualXYPlot(TH2F&) const;
00185 
00186         friend std::ostream& operator<<(std::ostream& s, const MapsSensor& ms);
00187 
00188         /**
00189          * Returns true if the specified coordinate falls in a dead area of the sensor
00190          */
00191         bool isDeadArea(const physXY) const;
00192 
00193         /** 
00194          * Converts a pixel x,y to a physical xy in the global coordinate system
00195          */
00196         void convertHitToPhysical(const coord&, physXY&) const;
00197 
00198         /**
00199          * Converts a physical xy to a pixel hit where possible.
00200          * 
00201          * Throws a MapsException if the hit falls in a dead area; application
00202          * code should check for this first with isDeadArea(physXY).
00203          */
00204         void convertPhysicalToHit(const physXY&, coord&) const throw(MapsException);
00205 
00206         /**
00207          * Prints all sort of information about this sensor's efficiency as a function of threshold
00208          */
00209         void printEfficiencies(std::ostream&);
00210 
00211         /**
00212          * Finds mutually dead areas as projected in the z direction for the supplied sensors.
00213          */
00214         static void mutualSensorMask(const std::vector<MapsSensor*>&, TH2F&);
00215         
00216         /**
00217          * Convenience method to decode the region for a given hit.
00218          */
00219         unsigned decodeRegion(const coord&) const;
00220         
00221         /**
00222          * Convenient method to decode the region from a given physical hit, if possible.
00223          */
00224         unsigned decodeRegion(const physXY&) const throw(MapsException);
00225 
00226 protected:
00227         MapsSensor& operator=(MapsSensor& ms) {
00228                 return *this;
00229         }
00230 
00231 private:
00232 
00233         MapsSensor(MapsSensor* ms);
00234 
00235         unsigned myId;
00236         double myPosition;
00237         double myPhi;
00238 
00239         /** 
00240          * The key is the threshold; the first element of the pair counts efficient hits,
00241          * the second counts inefficient hits.
00242          */
00243         std::map<unsigned, std::pair<unsigned, unsigned>* > myHitsByThreshold;
00244         std::map<unsigned, std::pair<unsigned, unsigned>* > myShaperHitsByThreshold;
00245         std::map<unsigned, std::pair<unsigned, unsigned>* >
00246                         mySamplerHitsByThreshold;
00247                         
00248         /**
00249          * All thresholds thusfar encountered in usage.
00250          */
00251         std::vector<unsigned> myKnownThresholds;
00252         
00253         /**
00254          * Allows for efficiency as a function of time to be studied.
00255          */
00256         std::map<unsigned, std::pair<unsigned, unsigned>* > myTimes;
00257 
00258         physXY myAlignment;
00259 
00260         std::vector<physXY > myResiduals;
00261         std::vector<physXY> myFourthHitResids;
00262 
00263         /**
00264          * Pixel coordinate of efficient hits
00265          */
00266         std::vector<MapsSensor::coord> myEfficientHits;
00267         //std::vector<MapsSensor::physXY> myEfficientPlaces;
00268         
00269         /**
00270          * Pixel coordinate of inefficient would-be hits
00271          */
00272         std::vector<MapsSensor::coord> myInefficientHits;
00273         
00274         /**
00275          * Physical coordinate (local system) of inefficient would-be hits
00276          */
00277         std::vector<MapsSensor::physXY> myInefficientPlaces;
00278         
00279         /**
00280          * Not in use yet.
00281          */
00282         std::vector<MapsSensor::coord> myGeneralHits;
00283         
00284         /**
00285          * This has to be private, since much efficiency based code depends on knowing
00286          * where we weren't efficient.
00287          */
00288         void registerTrackMiss(unsigned threshold, unsigned bx);
00289 
00290         /**
00291          * Returns the lowest threshold the sensor knows of
00292          */
00293         unsigned getLowestThresh() const;
00294         unsigned getHighestThresh() const;
00295 
00296         /**
00297          * Rotates hits from the local coordinate system to the global coordinate
00298          * system. Then you should align them.
00299          */
00300         void rotateLocalToGlobal(physXY&) const;
00301 
00302         /**
00303          * Rotates hits from the global coordinate system (POST alignment)
00304          * to the local system.
00305          */
00306         void rotateGlobalToLocal(physXY&) const;
00307 
00308         /**
00309          * Adds the alignment to the position.
00310          */
00311         void align(physXY&) const;
00312 
00313         /**
00314          * Subtracts the alignment from the position.
00315          */
00316         void malign(physXY&) const;
00317 
00318 };
00319 
00320 std::ostream& operator<<(std::ostream& s, const MapsSensor& ms);
00321 
00322 #endif /**MAPSSENSOR_HH_*/
00323 

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