From afb75f5c237c84368c1b95fef78682544cbf62bb Mon Sep 17 00:00:00 2001
From: "Stephen A. Wood" <saw@jlab.org>
Date: Fri, 18 Apr 2014 10:36:01 -0400
Subject: [PATCH] Experimental code to get parameters from CCDB.   CCDB must be
 installed and CCDB_HOME defined before compiling.   If CCDB_HOME is not
 defined, hcana is compiled without CCDB support   scons has not been updated
 to compile with CCDB support   To use, instead of gHcParms->Load(filename),
 do     gHcParms->OpenCCDB(runnum, ccdb_connection_string)    
 gHcParms->LoadCCDBDirectory("hms","h")    
 gHcParms->LoadCCDBDirectory("sos","s")    
 gHcParms->LoadCCDBDirectory("gen","g")   Parmaters will be loaded into the
 same internal gHcParms list as with   ThcParmList::Load, so no changes to
 detector classes are needed.   Scripts to convert existing parameters into
 CCDB are under development.   Currently all ccdb constants are loaded as
 doubles as there is not   a way to easily query ccdb to get the data type.  
 Also strings are not loaded.

---
 Makefile            | 14 +++++--
 src/THcParmList.cxx | 90 ++++++++++++++++++++++++++++++++++++++++++++-
 src/THcParmList.h   | 24 ++++++++++++
 3 files changed, 124 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 14cc55c..103db6a 100644
--- a/Makefile
+++ b/Makefile
@@ -139,6 +139,13 @@ ifdef WITH_DEBUG
 CXXFLAGS     += -DWITH_DEBUG
 endif
 
+CCDBLIBS = 
+CCDBFLAGS = 
+ifdef CCDB_HOME
+CCDBLIBS     += -L$(CCDB_HOME)/lib -lccdb
+CCDBFLAGS  += -I$(CCDB_HOME)/include -DWITH_CCDB
+endif
+
 ifdef PROFILE
 CXXFLAGS     += -pg
 LDFLAGS      += -pg
@@ -171,7 +178,8 @@ HALLALIBS    := -L$(LIBDIR) -lHallA -ldc -lscaler
 src/THcInterface.d:  $(HDR_COMPILEDATA)
 
 hcana:		src/main.o $(LIBDC) $(LIBSCALER) $(LIBHALLA) $(USERLIB)
-		$(LD) $(LDFLAGS) $< $(HALLALIBS) -L. -lHallC $(GLIBS) -o $@
+		$(LD) $(LDFLAGS) $< $(HALLALIBS) -L. -lHallC $(CCDBLIBS) \
+		$(GLIBS) -o $@
 
 $(USERLIB):	$(HDR) $(OBJS)
 		$(LD) $(LDFLAGS) $(SOFLAGS) -o $@ $(OBJS)
@@ -183,7 +191,7 @@ $(HDR_COMPILEDATA) $(LIBHALLA) $(LIBDC) $(LIBSCALER): $(ANALYZER)/Makefile
 
 $(USERDICT).cxx: $(RCHDR) $(HDR) $(LINKDEF)
 	@echo "Generating dictionary $(USERDICT)..."
-	$(ROOTBIN)/rootcint -f $@ -c $(INCLUDES) $^
+	$(ROOTBIN)/rootcint -f $@ -c $(INCLUDES) $(CCDBFLAGS) $^
 
 install:	all
 	cp -p $(USERLIB) $(HOME)/cue/SRC/ana
@@ -211,7 +219,7 @@ srcdist:
 .SUFFIXES: .c .cc .cpp .cxx .C .o .d
 
 %.o:	%.cxx
-	$(CXX) $(CXXFLAGS) -o $@ -c $<
+	$(CXX) $(CXXFLAGS) $(CCDBFLAGS) -o $@ -c $<
 
 # FIXME: this only works with gcc
 %.d:	%.cxx
diff --git a/src/THcParmList.cxx b/src/THcParmList.cxx
index a645b93..60e1f2b 100644
--- a/src/THcParmList.cxx
+++ b/src/THcParmList.cxx
@@ -10,6 +10,7 @@
 
 #include "TObjArray.h"
 #include "TObjString.h"
+#include "TSystem.h"
 
 #include "THcParmList.h"
 #include "THaVar.h"
@@ -17,7 +18,6 @@
 
 #include "TMath.h"
 
-
 /* #incluce <algorithm> include <fstream> include <cstring> */
 #include <iostream>
 #include <fstream>
@@ -579,3 +579,91 @@ void THcParmList::PrintFull( Option_t* option ) const
   THaVarList::PrintFull(option);
   TextList->Print();
 }
+#ifdef WITH_CCDB
+//_____________________________________________________________________________
+Int_t THcParmList::OpenCCDB(Int_t runnum)
+{
+  // Use the Environment variable "CCDB_CONNECTION" as the
+  // connection string
+  const char* connection_string = gSystem->Getenv("CCDB_CONNECTION");
+
+  return(OpenCCDB(runnum,connection_string));
+}
+Int_t THcParmList::OpenCCDB(Int_t runnum, const char* connection_string)
+{
+  // Connect to a CCDB database pointed to by connection_string
+
+  std::string s (connection_string);
+  CCDB_obj = new SQLiteCalibration(runnum);
+  Int_t result = CCDB_obj->Connect(s);
+  if(!result) return -1;	// Need some error codes
+  cout << "Opened " << s << " for run " << runnum << endl;
+  return 0;
+}
+Int_t THcParmList::CloseCCDB()
+{
+  delete CCDB_obj;
+  return(0);
+}
+Int_t THcParmList::LoadCCDBDirectory(const char* directory, 
+				     const char* prefix)
+{
+  // Load all parameters in directory
+  // Prepend prefix onto the name of each
+
+  std::string dirname (directory);
+
+  if(dirname[dirname.length()-1]!='/') {
+    dirname.append("/");
+  }
+  Int_t dirlen=dirname.length();
+
+  vector<string> namepaths;
+  CCDB_obj->GetListOfNamepaths(namepaths);
+  for(UInt_t iname=0;iname<namepaths.size();iname++) {
+    std::string varname (namepaths[iname]);
+    if(varname.compare(0,dirlen,dirname) == 0) {
+      varname.replace(0,dirlen,prefix);
+      //      cout << namepaths[iname] << " -> " << varname << endl;
+
+      // To what extent is there duplication here with Load() method?
+
+      // Retrieve the data as floats
+      vector<vector<double> > data;
+      CCDB_obj->GetCalib(data, namepaths[iname]);
+      for(UInt_t row=0; row<data.size(); row++) {
+      	for(UInt_t col=0;col<data[0].size(); col++) {
+      	  cout << data[row][col] << "\t";
+      	}
+      	cout << endl;
+      }
+      
+      if(data[0].size()==1) {	// Only handle single column tables
+	// Could stuff 2d arrays in, and assume that the application knows
+	// the number of columns.  Then the matrix stuff would just need to
+	// see if the variable exists, then copy the data into the right kind
+	// of structure instead of reading from the recon files.
+	THaVar* existingvar=Find(varname.c_str());
+	if(existingvar) {
+	  // Does the array of data need to deleted too?
+	  RemoveName(varname.c_str());
+	}
+	Double_t* fp = new Double_t[data.size()];
+	for(UInt_t row=0;row<data.size(); row++) {
+	  fp[row] = data[row][0];
+	}
+	// Need to append [size] to end of varname
+	char sizestring[20];
+	sprintf(sizestring,"[%d]",(Int_t) data.size());
+	std::string size_str (sizestring);
+	varname.append(size_str);
+	Define(varname.c_str(), "comment", *fp);
+      }
+
+    }
+  }
+  return 0;
+}
+
+#endif
+  
diff --git a/src/THcParmList.h b/src/THcParmList.h
index 830e6e7..d1a2fd6 100644
--- a/src/THcParmList.h
+++ b/src/THcParmList.h
@@ -10,8 +10,20 @@
 #include "THaVarList.h"
 #include "THaTextvars.h"
 
+#ifdef WITH_CCDB
+#ifdef __CINT__
+struct pthread_cond_t;
+struct pthread_mutex_t;
+#endif
+#include <CCDB/Calibration.h>
+#include <CCDB/SQLiteCalibration.h>
+using namespace ccdb;
+#endif
+
 using namespace std;
 
+
+
 class THcParmList : public THaVarList {
 
 public:
@@ -39,10 +51,22 @@ public:
   Int_t GetArray(const char* attr, Int_t* array, Int_t size);
   Int_t GetArray(const char* attr, Double_t* array, Int_t size);
 
+#ifdef WITH_CCDB
+  Int_t OpenCCDB(Int_t runnum);
+  Int_t OpenCCDB(Int_t runnum, const char* connection_string);
+  Int_t CloseCCDB();
+  Int_t LoadCCDBDirectory(const char* directory, 
+			  const char* prefix);
+#endif
+
 private:
 
   THaTextvars* TextList;
 
+#ifdef WITH_CCDB
+  SQLiteCalibration* CCDB_obj;
+#endif
+
   template<class T>
     Int_t ReadArray(const char* attrC, T* array, Int_t size);
 
-- 
GitLab