Index: /trunk/FACT++/src/PixelMap.h
===================================================================
--- /trunk/FACT++/src/PixelMap.h	(revision 11960)
+++ /trunk/FACT++/src/PixelMap.h	(revision 11960)
@@ -0,0 +1,176 @@
+#ifndef FACT_PixelMap
+#define FACT_PixelMap
+
+#include<vector>
+#include<string>
+#include<fstream>
+#include<sstream>
+
+#include "tools.h"
+
+#ifdef DEBUG
+#include<iostream>  // cerr -- to be removed?
+#endif
+
+struct PixelMapEntry
+{
+    int index;               /// Software index
+    int cbpx;                /// Hardware index as CBPX
+    int gapd;                /// gAPD Bias voltage
+    int hv_board;            /// Bias suppply board
+    int hv_channel;          /// Bias supply channel
+
+    int crate() const { return cbpx/1000; }
+    int board() const { return (cbpx/100)%10; }
+    int patch() const { return (cbpx/10)%10; }
+    int pixel() const { return cbpx%10; }
+    int hw() const    { return pixel()+patch()*9+board()*36+crate()*360; }
+    int group() const { return pixel()>4; }
+    int hv() const    { return hv_channel+hv_board*32; }
+};
+
+class PixelMap : public std::vector<PixelMapEntry>
+{
+public:
+    static const PixelMapEntry empty;
+
+    PixelMap() : std::vector<PixelMapEntry>(1440)
+    {
+    }
+
+    bool Read(const std::string &fname)
+    {
+        std::ifstream fin(fname);
+
+        int l = 0;
+
+        std::string buf;
+        while (getline(fin, buf, '\n'))
+        {
+            if (l>1439)
+                break;
+
+            buf = Tools::Trim(buf);
+            if (buf[0]=='#')
+                continue;
+
+            std::stringstream str(buf);
+
+            int   idummy;
+            float fdummy;
+
+            PixelMapEntry entry;
+
+            str >> entry.index;
+            str >> entry.cbpx;
+            str >> idummy;
+            str >> idummy;
+            str >> entry.gapd;
+            str >> fdummy;
+            str >> entry.hv_board;
+            str >> entry.hv_channel;
+            //str >> fdummy;
+            //str >> fdummy;
+            //str >> fdummy;
+
+            if (entry.hv_channel+32*entry.hv_board>=416/*BIAS::kNumChannels*/)
+            {
+#ifdef DEBUG
+                cerr << "Invalid board/channel read from FACTmapV5.txt." << endl;
+#endif
+                return false;
+            }
+
+            (*this)[l++] = entry;
+        }
+
+        return l==1440;
+    }
+
+    const PixelMapEntry &index(int idx) const
+    {
+        for (std::vector<PixelMapEntry>::const_iterator it=begin(); it!=end(); it++)
+            if (it->index==idx)
+                return *it;
+#ifdef DEBUG
+        std::cerr << "PixelMap: index " << idx << " not found" << std::endl;
+#endif
+        return empty;
+    }
+
+    const PixelMapEntry &cbpx(int c) const
+    {
+        for (std::vector<PixelMapEntry>::const_iterator it=begin(); it!=end(); it++)
+            if (it->cbpx==c)
+                return *it;
+#ifdef DEBUG
+        std::cerr << "PixelMap: cbpx " << c << " not found" << std::endl;
+#endif
+        return empty;
+    }
+
+    const PixelMapEntry &cbpx(int c, int b, int p, int px) const
+    {
+        return cbpx(px + p*9 + b*36 + c*360);
+    }
+
+    const PixelMapEntry &hv(int board, int channel) const
+    {
+        for (std::vector<PixelMapEntry>::const_iterator it=begin(); it!=end(); it++)
+            if (it->hv_board==board && it->hv_channel==channel)
+                return *it;
+#ifdef DEBUG
+        std::cerr << "PixelMap: hv " << board << "/" << channel << " not found" << std::endl;
+#endif
+        return empty;
+    }
+
+    const PixelMapEntry &hv(int idx) const
+    {
+        return hv(idx/32, idx%32);
+    }
+
+    float Vgapd(int board, int channel) const
+    {
+        float avg = 0;
+        int   num = 0;
+
+        for (std::vector<PixelMapEntry>::const_iterator it=begin(); it!=end(); it++)
+            if (it->hv_board==board && it->hv_channel==channel)
+            {
+                avg += it->gapd;
+                num ++;
+            }
+
+        return num==0 ? 0 : avg/num;
+    }
+
+    float Vgapd(int idx) const
+    {
+        return Vgapd(idx/32, idx%32);
+    }
+
+    std::vector<float> Vgapd() const
+    {
+        std::vector<float> avg;
+        std::vector<int>   num;
+
+        for (std::vector<PixelMapEntry>::const_iterator it=begin(); it!=end(); it++)
+        {
+            const int ch = it->hv_board*32 + it->hv_channel;
+
+            avg[ch] += it->gapd;
+            num[ch] ++;
+        }
+
+        for (int ch=0; ch<416; ch++)
+            if (num[ch])
+                avg[ch] /= num[ch];
+
+        return avg;
+    }
+};
+
+const PixelMapEntry PixelMap::empty = { 0, 0, 0, 0, 0 };
+
+#endif
