From 2393326d805209087cd8e8b7112e2aa1033546e3 Mon Sep 17 00:00:00 2001
From: "Stephen A. Wood" <saw@jlab.org>
Date: Tue, 14 Feb 2017 14:25:17 -0500
Subject: [PATCH] Initial draft of class to read Config (125) events   Provides
 methods get NSA, NSB, and NPED for each crate

---
 Makefile                    |   2 +-
 SConscript.py               |   2 +-
 src/HallC_LinkDef.h         |   1 +
 src/SConscript.py           |   2 +-
 src/THcConfigEvtHandler.cxx | 226 ++++++++++++++++++++++++++++++++++++
 src/THcConfigEvtHandler.h   |  77 ++++++++++++
 src/THcScalerEvtHandler.cxx |   2 +
 7 files changed, 309 insertions(+), 3 deletions(-)
 create mode 100644 src/THcConfigEvtHandler.cxx
 create mode 100644 src/THcConfigEvtHandler.h

diff --git a/Makefile b/Makefile
index 1da992b..22d0741 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@ SRC  =  src/THcInterface.cxx src/THcParmList.cxx src/THcAnalyzer.cxx \
 	src/THcRaster.cxx\
 	src/THcRasteredBeam.cxx\
 	src/THcRasterRawHit.cxx \
-	src/THcScalerEvtHandler.cxx \
+	src/THcScalerEvtHandler.cxx src/THcConfigEvtHandler.cxx \
 	src/THcHodoEff.cxx \
 	src/THcTrigApp.cxx src/THcTrigDet.cxx src/THcTrigRawHit.cxx \
 	src/THcRawAdcHit.cxx src/THcRawTdcHit.cxx \
diff --git a/SConscript.py b/SConscript.py
index d73fc0c..ab23e32 100644
--- a/SConscript.py
+++ b/SConscript.py
@@ -21,7 +21,7 @@ src/THcShowerArray.h src/THcShowerHit.h
 src/THcRawShowerHit.h src/THcAerogel.h src/THcAerogelHit.h src/THcCherenkov.h src/THcCherenkovHit.h
 src/THcGlobals.h src/THcDCTrack.h src/THcFormula.h
 src/THcRaster.h src/THcRasteredBeam.h src/THcRasterRawHit.h src/THcScalerEvtHandler.h
-src/THcHodoEff.h
+src/THcConfigEvtHandler.h src/THcHodoEff.h
 src/THcTrigApp.h src/THcTrigDet.h src/THcTrigRawHit.h
 src/THcRawAdcHit.h src/THcRawTdcHit.h
 src/THcDummySpectrometer.h
diff --git a/src/HallC_LinkDef.h b/src/HallC_LinkDef.h
index 2044547..29977d2 100644
--- a/src/HallC_LinkDef.h
+++ b/src/HallC_LinkDef.h
@@ -56,6 +56,7 @@
 #pragma link C++ class THcRasteredBeam+;
 #pragma link C++ class THcRasterRawHit+;
 #pragma link C++ class THcScalerEvtHandler+;
+#pragma link C++ class THcConfigEvtHandler+;
 #pragma link C++ class THcHodoEff+;
 #pragma link C++ class THcTrigApp+;
 #pragma link C++ class THcTrigDet+;
diff --git a/src/SConscript.py b/src/SConscript.py
index ee3f6a5..c9a05dc 100644
--- a/src/SConscript.py
+++ b/src/SConscript.py
@@ -26,7 +26,7 @@ THcAerogel.cxx THcAerogelHit.cxx
 THcCherenkov.cxx THcCherenkovHit.cxx
 THcFormula.cxx
 THcRaster.cxx THcRasteredBeam.cxx THcRasterRawHit.cxx
-THcScalerEvtHandler.cxx
+THcScalerEvtHandler.cxx THcConfigEvtHandler.cxx
 THcTrigApp.cxx THcTrigDet.cxx THcTrigRawHit.cxx
 THcRawAdcHit.cxx THcRawTdcHit.cxx
 THcDummySpectrometer.cxx
diff --git a/src/THcConfigEvtHandler.cxx b/src/THcConfigEvtHandler.cxx
new file mode 100644
index 0000000..4ede076
--- /dev/null
+++ b/src/THcConfigEvtHandler.cxx
@@ -0,0 +1,226 @@
+/** \class THcConfigEvtHandler
+    \ingroup base
+
+  Event handler for Hall C prestart config event.  Type 125
+
+  Example of an Event Type Handler for event type 125,
+  the hall C prestart event.
+
+  It was tested on some hms data.  However, note that I don't know what
+  these data mean yet and I presume the data structure is under development;
+  someone will need to modify this class (and the comments).
+
+  To use as a plugin with your own modifications, you can do this in
+  your analysis script
+
+  gHaEvtHandlers->Add (new THcConfigEvtHandler("hallcpre","for evtype 125"));
+
+  Global variables are defined in Init.  You can see them in Podd, as
+    analyzer [2] gHaVars->Print()
+
+     OBJ: THaVar	HCvar1	Hall C event type 125 variable 1
+     OBJ: THaVar	HCvar2	Hall C event type 125 variable 2
+     OBJ: THaVar	HCvar3	Hall C event type 125 variable 3
+     OBJ: THaVar	HCvar4	Hall C event type 125 variable 4
+
+  The data can be added to the ROOT Tree "T" using the output
+  definition file.  Then you can see them, for example as follows
+
+     T->Scan("HCvar1:HCvar2:HCvar3:HCvar4")
+
+\author Robert Michaels (rom@jlab.org), updated by Stephen Wood (saw@jlab.org)
+*/
+
+#include "THcConfigEvtHandler.h"
+#include "THaEvData.h"
+#include "THaVarList.h"
+#include <cstring>
+#include <cstdio>
+#include <cstdlib>
+#include <iostream>
+
+using namespace std;
+
+THcConfigEvtHandler::THcConfigEvtHandler(const char *name, const char* description)
+  : THaEvtTypeHandler(name,description)
+{
+}
+
+THcConfigEvtHandler::~THcConfigEvtHandler()
+{
+}
+
+//Float_t THcConfigEvtHandler::GetData(const std::string& tag)
+//{
+//  // A public method which other classes may use
+//  if (theDataMap.find(tag) == theDataMap.end())
+//    return 0;
+// return theDataMap[tag];
+//}
+
+
+Int_t THcConfigEvtHandler::Analyze(THaEvData *evdata)
+{
+
+  Bool_t ldebug = true;  // FIXME: use fDebug
+
+  if ( !IsMyEvent(evdata->GetEvType()) ) return -1;
+
+  if (ldebug) cout << "------------------\n  Event type 125"<<endl;
+
+  Int_t evlen = evdata->GetEvLength();
+  Int_t ip = 0;
+  ip++;
+  UInt_t thisword = evdata->GetRawData(ip);
+  Int_t roc = thisword & 0xff;
+  cout << "THcConfigEvtHandler: " << roc << endl;
+  // Should check if this roc has already been seen
+  CrateInfo_t *cinfo = new CrateInfo_t;
+  cinfo->FADC250.nmodules=0;
+  cinfo->FADC250.present=0;
+  cinfo->CAEN1190.present=0;
+  CrateInfoMap.insert(std::make_pair(roc, cinfo));
+  ip++;
+  // Three possible blocks of config data
+  // 0xdafadc01 - FADC information for the crate
+  // 0xdafadcff - Set of threshold by slot/channel
+  // 0xdedc1190 - 1190 TDC information for the crate
+  thisword = evdata->GetRawData(ip);
+  while(ip<evlen) {
+    if (thisword == 0xdafadcff) {
+      ip++;
+      thisword = evdata->GetRawData(ip);
+      cout << "ADC thresholds for slots ";
+      while((thisword & 0xfffff000)==0xfadcf000) {
+        Int_t slot = thisword&0x1f;
+        // Should check if this slot has already been SDC_WIRE_CENTER
+        cinfo->FADC250.nmodules++;
+        cout << " " << slot;
+        Int_t *thresholds = new Int_t [16];
+        cinfo->FADC250.thresholds.insert(std::make_pair(slot, thresholds));
+        for(Int_t i=0;i<16;i++) {
+          thresholds[i] = evdata->GetRawData(ip+i);
+        }
+        ip +=18;
+        if(ip>=evlen) {
+          if(ip>evlen) {
+            cout << endl << "Info event truncated" << endl;
+          }
+          break;
+        }
+        thisword = evdata->GetRawData(ip);
+      }
+      cout << endl;
+    } else if((thisword&0xffffff00) == 0xdafadc00) { // FADC250 information
+      cout << "ADC information: Block level " << (thisword&0xff) << endl;
+      cinfo->FADC250.present = 1;
+      cinfo->FADC250.blocklevel = thisword&0xff;
+      cinfo->FADC250.daq_level = evdata->GetRawData(ip+2);
+      cinfo->FADC250.threshold = evdata->GetRawData(ip+3);
+      cinfo->FADC250.mode = evdata->GetRawData(ip+4);
+      cinfo->FADC250.window_lat = evdata->GetRawData(ip+5);
+      cinfo->FADC250.window_width = evdata->GetRawData(ip+6);
+      cinfo->FADC250.nsb = evdata->GetRawData(ip+7);
+      cinfo->FADC250.nsa = evdata->GetRawData(ip+8);
+      cinfo->FADC250.np = evdata->GetRawData(ip+9);
+      cinfo->FADC250.nped = evdata->GetRawData(ip+10);
+      cinfo->FADC250.maxped = evdata->GetRawData(ip+11);
+      cinfo->FADC250.nsat = evdata->GetRawData(ip+12);
+      ip += 13;
+      thisword = evdata->GetRawData(ip);
+    } else if (thisword == 0xdedc1190) { // CAEN 1190 information
+      cout << "TDC information" << endl;
+      cinfo->CAEN1190.present = 1;
+      cinfo->CAEN1190.resolution = evdata->GetRawData(ip+2);
+      cinfo->CAEN1190.timewindow_offset = evdata->GetRawData(ip+3);
+      cinfo->CAEN1190.timewindow_width = evdata->GetRawData(ip+4);
+      ip += 6;
+      thisword = evdata->GetRawData(ip);
+    } else {
+      cout << "Expected header missing" << endl;
+      cout << ip << " " << hex << thisword << dec << endl;
+      ip = evlen;
+    }
+  }
+
+  return 1;
+}
+
+void THcConfigEvtHandler::PrintConfig()
+{
+/**
+  Stub of method to pretty print the config data
+*/
+  cout << "Configuration Data" << endl;
+  std::map<Int_t, CrateInfo_t *>::iterator it = CrateInfoMap.begin();
+  while(it != CrateInfoMap.end()) {
+    Int_t roc = it->first;
+    CrateInfo_t *cinfo = it->second;
+    cout<<roc<<" "<<cinfo->FADC250.present<< " " << cinfo->CAEN1190.present << endl;
+    it++;
+  }
+}
+Int_t THcConfigEvtHandler::GetNSA(Int_t crate) {
+  if(CrateInfoMap.find(crate)!=CrateInfoMap.end()) {
+    CrateInfo_t *cinfo = CrateInfoMap[crate];
+    if(cinfo->FADC250.present > 0) return(cinfo->FADC250.nsa);
+  }
+  return(-1);
+}
+Int_t THcConfigEvtHandler::GetNSB(Int_t crate) {
+  if(CrateInfoMap.find(crate)!=CrateInfoMap.end()) {
+    CrateInfo_t *cinfo = CrateInfoMap[crate];
+    if(cinfo->FADC250.present > 0) return(cinfo->FADC250.nsb);
+  }
+  return(-1);
+}
+Int_t THcConfigEvtHandler::GetNPED(Int_t crate) {
+  if(CrateInfoMap.find(crate)!=CrateInfoMap.end()) {
+    CrateInfo_t *cinfo = CrateInfoMap[crate];
+    if(cinfo->FADC250.present > 0) return(cinfo->FADC250.nped);
+  }
+  return(-1);
+}
+void THcConfigEvtHandler::AddEventType(Int_t evtype)
+{
+  eventtypes.push_back(evtype);
+}
+
+THaAnalysisObject::EStatus THcConfigEvtHandler::Init(const TDatime& date)
+{
+
+  cout << "Howdy !  We are initializing THcConfigEvtHandler !!   name =   "<<fName<<endl;
+
+  if(eventtypes.size()==0) {
+    eventtypes.push_back(125);  // what events to look for
+  }
+
+// dvars is a member of this class.
+// The index of the dvars array track the array of global variables created.
+// This is just a fake example with 4 variables.
+// Please change these comments when you modify this class.
+
+  NVars = 4;
+  dvars = new Double_t[NVars];
+  memset(dvars, 0, NVars*sizeof(Double_t));
+  if (gHaVars) {
+      cout << "EvtHandler:: Have gHaVars.  Good thing. "<<gHaVars<<endl;
+  } else {
+      cout << "EvtHandler:: No gHaVars ?!  Well, that is a problem !!"<<endl;
+      return kInitError;
+  }
+  const Int_t* count = 0;
+  char cname[80];
+  char cdescription[80];
+  for (UInt_t i = 0; i < NVars; i++) {
+    sprintf(cname,"HCvar%d",i+1);
+    sprintf(cdescription,"Hall C event type 125 variable %d",i+1);
+    gHaVars->DefineByType(cname, cdescription, &dvars[i], kDouble, count);
+  }
+
+
+  fStatus = kOK;
+  return kOK;
+}
+
+ClassImp(THcConfigEvtHandler)
diff --git a/src/THcConfigEvtHandler.h b/src/THcConfigEvtHandler.h
new file mode 100644
index 0000000..07007fd
--- /dev/null
+++ b/src/THcConfigEvtHandler.h
@@ -0,0 +1,77 @@
+#ifndef THcConfigEvtHandler_
+#define THcConfigEvtHandler_
+
+/////////////////////////////////////////////////////////////////////
+//
+//   THcConfigEvtHandler
+//   For more details see the implementation file.
+//   This handles hall C's event type 125.
+//   author  Robert Michaels (rom@jlab.org)
+//
+/////////////////////////////////////////////////////////////////////
+
+#include "THaEvtTypeHandler.h"
+#include <string>
+#include <vector>
+#include <map>
+
+class THcConfigEvtHandler : public THaEvtTypeHandler {
+
+public:
+
+  THcConfigEvtHandler(const char* name, const char* description);
+  virtual ~THcConfigEvtHandler();
+
+  virtual Int_t Analyze(THaEvData *evdata);
+  virtual void AddEventType(Int_t evtype);
+  virtual void PrintConfig();
+  virtual Int_t GetNSA(Int_t crate);
+  virtual Int_t GetNSB(Int_t crate);
+  virtual Int_t GetNPED(Int_t crate);
+  virtual EStatus Init( const TDatime& run_time);
+ //  Float_t GetData(const std::string& tag);
+
+private:
+
+//  std::map<std::string, Float_t> theDataMap;
+  std::vector<std::string> dataKeys;
+  UInt_t NVars;
+  Double_t *dvars;
+
+  typedef struct {
+    struct FADC250 {
+      Int_t present;
+      Int_t daq_level;
+      Int_t threshold;
+      Int_t mode;
+      Int_t window_lat;
+      Int_t window_width;
+      Int_t nsb;
+      Int_t nsa;
+      Int_t np;
+      Int_t nped;
+      Int_t maxped;
+      Int_t nsat;
+      Int_t nmodules;
+      Int_t blocklevel;
+      std::map<Int_t, Int_t *> thresholds;
+   } FADC250;
+   struct CAEN1190 {
+      Int_t present;
+      Int_t resolution;
+      Int_t timewindow_offset;
+      Int_t timewindow_width;
+   } CAEN1190;
+   //CrateInfo : FADC250.nmodules(0),CAEN1190.present(0) {}
+  } CrateInfo_t;
+
+  std::map<Int_t, CrateInfo_t *> CrateInfoMap;
+
+  THcConfigEvtHandler(const THcConfigEvtHandler& fh);
+  THcConfigEvtHandler& operator=(const THcConfigEvtHandler& fh);
+
+  ClassDef(THcConfigEvtHandler,0)  // Hall C event type 125
+
+};
+
+#endif
diff --git a/src/THcScalerEvtHandler.cxx b/src/THcScalerEvtHandler.cxx
index 81bbb45..7452bb5 100644
--- a/src/THcScalerEvtHandler.cxx
+++ b/src/THcScalerEvtHandler.cxx
@@ -50,6 +50,8 @@ To enable debugging you may try this in the setup script
 #include <cstdlib>
 #include <iostream>
 #include <sstream>
+#include <map>
+#include <iterator>
 #include "THaVarList.h"
 #include "VarDef.h"
 
-- 
GitLab