pdscalibdata/src/CsPadFilterV1.cpp

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: CsPadFilterV1.cpp 5249 2013-01-30 17:52:59Z salnikov@SLAC.STANFORD.EDU $
00004 //
00005 // Description:
00006 //      Class CsPadFilterV1...
00007 //
00008 // Author List:
00009 //      Andrei Salnikov
00010 //
00011 //------------------------------------------------------------------------
00012 
00013 //-----------------------
00014 // This Class's Header --
00015 //-----------------------
00016 #include "pdscalibdata/CsPadFilterV1.h"
00017 
00018 //-----------------
00019 // C/C++ Headers --
00020 //-----------------
00021 #include <algorithm>
00022 #include <fstream>
00023 #include <stdexcept>
00024 
00025 //-------------------------------
00026 // Collaborating Class Headers --
00027 //-------------------------------
00028 #include "MsgLogger/MsgLogger.h"
00029 
00030 //-----------------------------------------------------------------------
00031 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00032 //-----------------------------------------------------------------------
00033 
00034 namespace {
00035   
00036   const char logger[] = "CsPadFilterV1";
00037   
00038   // Predicate for counting 
00039   struct HigherThan {
00040     HigherThan(int min) : m_min(min) {}
00041     
00042     bool operator()(int val) const { return val > m_min; }
00043     
00044     int m_min;
00045   };
00046   
00047 }
00048 
00049 //              ----------------------------------------
00050 //              -- Public Function Member Definitions --
00051 //              ----------------------------------------
00052 
00053 namespace pdscalibdata {
00054 
00055 //----------------
00056 // Constructors --
00057 //----------------
00058 CsPadFilterV1::CsPadFilterV1 ()
00059   : m_mode(uint32_t(None))
00060 {
00061   std::fill_n(m_data, int(DataSize), 0.0);
00062 }
00063 
00064 CsPadFilterV1::CsPadFilterV1 (const std::string& fname) 
00065   : m_mode(uint32_t(None))
00066 {
00067   std::fill_n(m_data, int(DataSize), 0.0);
00068   
00069   // open file
00070   std::ifstream in(fname.c_str());
00071   if (not in.good()) {
00072     const std::string msg = "Failed to open cspad filter file: "+fname;
00073     MsgLogRoot(error, msg);
00074     throw std::runtime_error(msg);
00075   }
00076 
00077   // read first number into a mode
00078   if (not (in >> m_mode)) {
00079     const std::string msg = "cspad filter file does not have enough data: "+fname;
00080     MsgLogRoot(error, msg);
00081     throw std::runtime_error(msg);
00082   }
00083 
00084   // read whatever left into the array
00085   // TODO: some error checking, what if non-number appears in a file
00086   double* it = m_data;
00087   size_t count = 0;
00088   while(in and count != DataSize) {
00089     in >> *it++;
00090     ++ count;
00091   }
00092 
00093   MsgLog(logger, trace, "CsPadFilterV1: mode=" << m_mode << " data=" << m_data[0] << "," << m_data[1]);
00094   
00095 }
00096 
00097 CsPadFilterV1::CsPadFilterV1 (FilterMode mode, const double data[DataSize]) 
00098   : m_mode(uint32_t(mode))
00099 {
00100   std::copy(data, data+DataSize, m_data);
00101   MsgLog(logger, trace, "CsPadFilterV1: mode=" << m_mode << " data=" << m_data[0] << "," << m_data[1]);
00102 }
00103 
00104 //--------------
00105 // Destructor --
00106 //--------------
00107 CsPadFilterV1::~CsPadFilterV1 ()
00108 {
00109 }
00110 
00111 bool
00112 CsPadFilterV1::filter(const ndarray<const int16_t, 3>& pixelData) const
00113 {
00114   if (m_mode == None) return true;
00115   
00116   unsigned count = std::count_if(pixelData.begin(), pixelData.end(), ::HigherThan(int(m_data[0])));
00117   
00118   MsgLog(logger, debug, "CsPadFilterV1::filter - " << count << " pixels above " << m_data[0]);
00119   
00120   if (m_data[1] < 0) {
00121     // m_data[0] is a percentage
00122     return count > -m_data[1]/100*pixelData.size();
00123   } else {
00124     // m_data[0] is absolute pixel count
00125     return count > m_data[1];
00126   }
00127 
00128 }
00129 
00130 bool
00131 CsPadFilterV1::filter(const ndarray<const int16_t, 3>& pixelData, const ndarray<const uint16_t, 3>& pixelStatus) const
00132 {
00133   if (m_mode == None) return true;
00134 
00135   if (pixelData.size() != pixelStatus.size()) {
00136     MsgLog(logger, debug, "CsPadFilterV1::filter - pixel data array and pixel status array have different sizes");
00137     return false;
00138   }
00139 
00140   // calculate number of pixels exceeding m_data[0] threshold,
00141   // only take pixels with good status (=0)
00142   unsigned count = 0;
00143   int threshold = int(m_data[0]);
00144   typedef ndarray<const int16_t, 3>::iterator Iter;
00145   ndarray<const uint16_t, 3>::iterator stat_iter = pixelStatus.begin();
00146   for (Iter data_iter = pixelData.begin(); data_iter != pixelData.end(); ++ data_iter, ++ stat_iter) {
00147     if (*stat_iter == 0 and *data_iter > threshold) ++ count;
00148   }
00149 
00150   MsgLog(logger, debug, "CsPadFilterV1::filter - " << count << " pixels above " << m_data[0]);
00151 
00152   if (m_data[1] < 0) {
00153     // m_data[0] is a percentage
00154     return count > -m_data[1]/100*pixelData.size();
00155   } else {
00156     // m_data[0] is absolute pixel count
00157     return count > m_data[1];
00158   }
00159 }
00160 
00161 } // namespace pdscalibdata

Generated on 19 Dec 2016 for PSANAmodules by  doxygen 1.4.7