Newer
Older
TB_Chris / TbKernel / src / .svn / text-base / TbPixelSvc.h.svn-base
  1. #ifndef TBPIXELSVC_H
  2. #define TBPIXELSVC_H
  3.  
  4. // Gaudi
  5. #include "GaudiKernel/Service.h"
  6. #include "GaudiKernel/Bootstrap.h"
  7. #include "GaudiKernel/MsgStream.h"
  8.  
  9. // Local
  10. #include "TbKernel/ITbPixelSvc.h"
  11. #include "TbKernel/ITbGeometrySvc.h"
  12.  
  13. #include <stdint.h>
  14.  
  15. // struct PixelConfig;
  16. template <class TYPE>
  17. class SvcFactory;
  18.  
  19. /** @class TbPixelSvc TbPixelSvc.h
  20. *
  21. * Implementation of the Timepix3 pixel configuration service.
  22. *
  23. */
  24.  
  25. class TbPixelSvc : public extends1<Service, ITbPixelSvc> {
  26.  
  27. public:
  28. /// Constructor
  29. TbPixelSvc(const std::string& name, ISvcLocator* svc);
  30. /// Destructor
  31. virtual ~TbPixelSvc();
  32.  
  33. virtual StatusCode initialize();
  34.  
  35. /// Get the pixel address for a given column and row.
  36. virtual unsigned int address(const unsigned int col,
  37. const unsigned int row) const {
  38. // Get the double-column and super-pixel.
  39. const unsigned int dcol = col / 2;
  40. const unsigned int spix = row / 4;
  41. // Get the pixel number within the superpixel.
  42. unsigned int pix = row % 4;
  43. if (1 == col % 2) pix += 4;
  44. return (dcol << 9) + (spix << 3) + pix;
  45. }
  46. std::pair<unsigned int, unsigned int> posFromAddress( const unsigned int& address ) const {
  47. std::pair<unsigned int, unsigned int> pos;
  48. // Decode the pixel address, first get the double column.
  49. const unsigned int dcol = (0xFE00 & address) >> 8;
  50. // Get the super pixel address.
  51. const unsigned int spix = (0x01F8 & address) >> 1;
  52. // Get the address of the pixel within the super pixel.
  53. const unsigned int pix = (0x0007 & address);
  54. // Calculate the row and column numbers.
  55. pos.first = dcol + pix / 4;
  56. pos.second = spix + (pix & 0x3);
  57. return pos;
  58. }
  59.  
  60. /// Return whether the pixel has been masked.
  61. virtual bool isMasked(const unsigned int address,
  62. const unsigned int device) const {
  63. return m_pixelConfiguration[device][address].isMasked ||
  64. m_pixelConfiguration[device][address].trimDac_isMasked;
  65. }
  66.  
  67. /// Correct the timestamp of a given hit.
  68. virtual void applyPhaseCorrection(LHCb::TbHit* h) {
  69. h->setTime(h->time() +
  70. m_pixelConfiguration[h->device()][h->pixelAddress()].tOffset);
  71. }
  72.  
  73. /// Set the clock phase correction.
  74. virtual void setPhase(const unsigned int device,
  75. const unsigned int pll_config, const int amplitude);
  76.  
  77. /// Set trim DACs.
  78. virtual void setTrim(const unsigned int device, const char* data);
  79.  
  80. /// Convert time-over-threshold to charge.
  81. virtual double charge(const unsigned int tot, const unsigned int address,
  82. const unsigned int device) const {
  83. const PixelConfig& conf = m_pixelConfiguration[device][address];
  84. double value=inverseSurrogate(tot, conf.p1, conf.p0, conf.c, conf.t);
  85. if( isnan(value) ){
  86. auto pos = posFromAddress( address );
  87. warning() << "Pixel " << device << "/0x"
  88. << std::hex << address << std::dec << " tot = " << tot
  89. << " (" << pos.first << ", " << pos.second
  90. << ")" << conf.p1 << " " << conf.p0 << " " << conf.c << " " << conf.t << endmsg;
  91. return 1;
  92. }
  93. return value;
  94. }
  95.  
  96. private:
  97. /// Allow SvcFactory to instantiate the service.
  98. friend class SvcFactory<TbPixelSvc>;
  99.  
  100. struct PixelConfig {
  101. PixelConfig()
  102. : isMasked(false),
  103. trimDac_isMasked(false),
  104. isDead(false),
  105. tp_ena(0),
  106. trim(4),
  107. tOffset(0),
  108. p0(0),
  109. p1(1),
  110. c(0),
  111. t(0) {};
  112. bool isMasked;
  113. bool trimDac_isMasked;
  114. bool isDead;
  115. bool tp_ena;
  116. uint8_t trim;
  117. int tOffset;
  118. /// Parameters of surrogate function
  119. float p0;
  120. float p1;
  121. float c;
  122. float t;
  123. };
  124.  
  125.  
  126. void resetClockPhase(const unsigned int device);
  127. /// Add a constant offset in time to a single super column.
  128. void addOffset(const int offset, const unsigned int device,
  129. const unsigned int dcol);
  130.  
  131. /// Pixel configuration for each chip
  132. std::vector<std::vector<PixelConfig> > m_pixelConfiguration;
  133.  
  134. void printConfig( const unsigned int& plane, const unsigned int& address){
  135. auto pos = posFromAddress(address);
  136. PixelConfig& conf = m_pixelConfiguration[plane][address];
  137. info() << std::hex << "0x" << address << std::dec << " = ("<<pos.first << ", " << pos.second << ") : " << conf.p0 << " " << conf.p1 << " " << conf.c << " " << conf.t << endmsg;
  138. }
  139. /// Functionality to write out the trim dacs written into the header
  140. bool m_writeTrimDACs;
  141. void writeTrimDAC(const unsigned int device);
  142.  
  143. /// ignore PLL config
  144. std::vector<bool> m_protectPhase;
  145. /// Surrogate function, taken from http://arxiv.org/pdf/1103.2739v3.pdf
  146. double surrogate(const double& charge, const double& a, const double& b,
  147. const double& c, const double& t) const {
  148. double result = 0.;
  149. const double r = (b + a * t);
  150. const double d = r * r + 4 * a * c;
  151. if (d > 0.) {
  152. const double itcpt = ((t * a - b) + sqrt(d)) / (2 * a);
  153. if (charge > itcpt) {
  154. result = a * charge + b - c / (charge - t);
  155. }
  156. }
  157. return result;
  158. }
  159.  
  160. double inverseSurrogate(const uint32_t tot, const double a, const double b,
  161. const double c, const double t) const {
  162. double result = 1.;
  163. const double r = (b + a * t - tot);
  164. const double d = r * r + 4. * a * c;
  165. if (d > 0.) {
  166. result = (a * t + tot - b + sqrt(d)) / (2. * a);
  167. }
  168. return result;
  169. }
  170.  
  171. bool readConditions(const std::string& file);
  172.  
  173. /// Pointer to geometry service
  174. mutable ITbGeometrySvc* m_geomSvc;
  175. /// Access geometry service on-demand
  176. ITbGeometrySvc* geomSvc() const {
  177. if (!m_geomSvc) {
  178. m_geomSvc = Gaudi::svcLocator()->service<ITbGeometrySvc>("TbGeometrySvc");
  179. }
  180. return m_geomSvc;
  181. }
  182. /// Pointer to message stream
  183. mutable MsgStream* m_msg;
  184. /// On-demand access to message stream
  185. MsgStream& msg() const {
  186. if (!m_msg) m_msg = new MsgStream(msgSvc(), name());
  187. return *m_msg;
  188. }
  189. };
  190.  
  191. #endif