Index: trunk/FACT++/src/PixelMap.cc
===================================================================
--- trunk/FACT++/src/PixelMap.cc	(revision 13166)
+++ trunk/FACT++/src/PixelMap.cc	(revision 13167)
@@ -1,4 +1,115 @@
 #include "PixelMap.h"
+
+#include <boost/regex.hpp>
+
+//#ifdef HAS_SQL
+#include <mysql++/mysql++.h>
+//#endif
+
+using namespace std;
 
 const PixelMapEntry PixelMap::empty = { -1, 0, 0, 0, 0 };
 const BiasMapEntry  BiasMap::empty  = { -1, 0, 0, 0 };
+
+void BiasMap::Read(const std::string &fname)
+{
+    std::ifstream fin(fname);
+
+    int l = 0;
+
+    std::string buf;
+    while (getline(fin, buf, '\n'))
+    {
+        if (l>416)
+            break;
+
+        buf = Tools::Trim(buf);
+        if (buf[0]=='#')
+            continue;
+
+        std::stringstream str(buf);
+
+        BiasMapEntry entry;
+
+        str >> entry.hv_board;
+        str >> entry.hv_channel;
+        str >> entry.Vnom;
+        str >> entry.Voff;
+
+        if (entry.hv_channel+32*entry.hv_board>=416)
+            throw runtime_error("Invalid board/channel read from "+fname+".");
+
+        (*this)[entry.hv()] = entry;
+
+        l++;
+    }
+
+    if (l!=416)
+        throw runtime_error("Number of lines read from "+fname+" does not match 416.");
+
+    if (size()!=416)
+        throw runtime_error("Number of entries read from "+fname+" does not match 416.");
+}
+
+void BiasMap::Retrieve(const std::string &database)
+{
+    static const boost::regex expr("(([[:word:].-]+)(:(.+))?@)?([[:word:].-]+)(:([[:digit:]]+))?(/([[:word:].-]+))");
+    // 2: user
+    // 4: pass
+    // 5: server
+    // 7: port
+    // 9: db
+
+    boost::smatch what;
+    if (!boost::regex_match(database, what, expr, boost::match_extra))
+        throw runtime_error("Couldn't parse '"+database+"'.");
+
+    if (what.size()!=10)
+        throw runtime_error("Error parsing '"+database+"'.");
+
+    const string user   = what[2];
+    const string passwd = what[4];
+    const string server = what[5];
+    const string db     = what[9];
+    const int port      = atoi(string(what[7]).c_str());
+
+    mysqlpp::Connection conn(db.c_str(), server.c_str(), user.c_str(), passwd.c_str(), port);
+
+    const mysqlpp::StoreQueryResult res =
+        conn.query("SELECT fPatchNumber, AVG(fVoltageNom), fOffset "
+                   " FROM GapdVoltages "
+                   " LEFT JOIN BiasOffsets USING(fPatchNumber) "
+                   " GROUP BY fPatchNumber").store();
+
+    clear();
+
+    int l = 0;
+    for (vector<mysqlpp::Row>::const_iterator v=res.begin(); v<res.end(); v++)
+    {
+        const int id = (*v)[0];
+
+        if (id<0 || id>416)
+        {
+            ostringstream str;
+            str << "Invalid channel id " << id << " received from database.";
+            throw runtime_error(str.str());
+        }
+
+        BiasMapEntry entry;
+
+        entry.hv_board   = id/32;
+        entry.hv_channel = id%32;
+        entry.Vnom       = (*v)[1];
+        entry.Voff       = (*v)[2];
+
+        (*this)[id] = entry;
+
+        l++;
+    }
+
+    if (l!=416)
+        throw runtime_error("Number of rows retrieved from the database does not match 416.");
+
+    if (size()!=416)
+        throw runtime_error("Number of entries retrived from database does not match 416.");
+}
Index: trunk/FACT++/src/PixelMap.h
===================================================================
--- trunk/FACT++/src/PixelMap.h	(revision 13166)
+++ trunk/FACT++/src/PixelMap.h	(revision 13167)
@@ -204,42 +204,6 @@
     }
 
-    bool Read(const std::string &fname)
-    {
-        std::ifstream fin(fname);
-
-        int l = 0;
-
-        std::string buf;
-        while (getline(fin, buf, '\n'))
-        {
-            if (l>416)
-                break;
-
-            buf = Tools::Trim(buf);
-            if (buf[0]=='#')
-                continue;
-
-            std::stringstream str(buf);
-
-            BiasMapEntry entry;
-
-            str >> entry.hv_board;
-            str >> entry.hv_channel;
-            str >> entry.Vnom;
-            str >> entry.Voff;
-
-            if (entry.hv_channel+32*entry.hv_board>=416)
-            {
-#ifdef DEBUG
-                cerr << "Invalid board/channel read from " << fname << "." << endl;
-#endif
-                return false;
-            }
-
-            (*this)[l++] = entry;
-        }
-
-        return l==416;
-    }
+    void Retrieve(const std::string &database);
+    void Read(const std::string &fname);
 
     const BiasMapEntry &hv(int board, int channel) const
