Newer
Older
/** \class THcConfigEvtHandler
\brief Analyze Hall C Configuration events. (Event type 125).
Hall C Configuration events contain information such as FADC250
thresholds, mode settings, window settings, pulse mode settings, etc.
or CAEN1190 window and resolution settings.
gHaEvtHandlers->Add (new THcConfigEvtHandler("hallcpre","for evtype 125"));
to the analysis script. The first argument ("hallcpre") is an arbitrary
name that will be used to construct THcParmList type parameters with names
of the form ghallcpre_*. These parameters hold the configuration information
that is found in the events.
All the configuation data can also be printed out with the PrintConfig method
\author Stephen Wood (saw@jlab.org)
*/
#include "THcConfigEvtHandler.h"
#include "THaEvData.h"
#include "THaGlobals.h"
#include "THcGlobals.h"
#include "THcParmList.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h" //support for stdout logging
#include "spdlog/sinks/basic_file_sink.h" // support for basic file logging
using namespace std;
THcConfigEvtHandler::THcConfigEvtHandler(const char *name, const char* description)
: hcana::ConfigLogging<THaEvtTypeHandler>(name,description)
{
}
THcConfigEvtHandler::~THcConfigEvtHandler()
{
// TODO: remove the parameters we've added to gHcParms
DeleteCrateInfoMap();
}
//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];
//}
void THcConfigEvtHandler::DeleteCrateInfoMap()
{
// Clear the CrateInfoMap, deallocating its elements' dynamic memory
//TODO: don't manage memory manually, contain the object, use STL vectors
typedef std::map<Int_t, CrateInfo_t *> cmap_t;
typedef std::map<Int_t, Int_t *> imap_t;
for( cmap_t::iterator it = CrateInfoMap.begin();
it != CrateInfoMap.end(); ++it ) {
CrateInfo_t* cinfo = it->second;
if( cinfo ) {
for( imap_t::iterator jt = cinfo->FADC250.thresholds.begin();
jt != cinfo->FADC250.thresholds.end(); ++jt ) {
delete [] jt->second;
}
delete cinfo;
}
}
CrateInfoMap.clear();
}
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;
}
_logger->debug("--- Event type 125 ---");
Int_t evlen = evdata->GetEvLength();
Int_t ip = 0;
ip++;
UInt_t thisword = evdata->GetRawData(ip);
Int_t roc = thisword & 0xff;
_logger->info("THcConfigEvtHandler: {} ", roc);
//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;
cinfo->TI.present=0;
// FIXME: check if entry for this roc already present in the map
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
while(ip<evlen) {
thisword = evdata->GetRawData(ip);
if (thisword == 0xdafadcff) {
ip++;
thisword = evdata->GetRawData(ip);
std::string adc_th_string;
//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;
adc_th_string += std::string(" ");
adc_th_string += std::to_string(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+1+i);
}
ip +=18;
if(ip>=evlen) {
if(ip>evlen) {
//cout << endl << "Info event truncated" << endl;
adc_th_string += std::string(" ... truncated ");
}
break;
}
thisword = evdata->GetRawData(ip);
}
//cout << endl;
_logger->info("ADC thresholds for slots {}", adc_th_string);
} else if((thisword&0xffffff00) == 0xdafadc00) { // FADC250 information
//cout << "ADC information: Block level " << (thisword&0xff) << endl;
_logger->info("ADC information: Block level {} " , (thisword&0xff));
cinfo->FADC250.present = 1;
cinfo->FADC250.blocklevel = thisword&0xff;
cinfo->FADC250.dac_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;
} else if (thisword == 0xdedc1190) { // CAEN 1190 information
//cout << "TDC information" << endl;
_logger->info("TDC information");
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;
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
} else if (thisword == 0xd0000000) { // TI setup data
cinfo->TI.present = 1;
ip += 1;
UInt_t versionword = evdata->GetRawData(ip++);
if((versionword & 0xffff0000) != 0xabcd0000) {
cout << "Unexpected TI info word " << hex << thisword << dec << endl;
cout << " Expected 0xabcdNNNN" << endl;
ip += 1;
} else {
Int_t version = versionword & 0xffff;
cinfo->TI.num_prescales = 6;
cinfo->TI.nped = evdata->GetRawData(ip++);
if(version >= 2) {
cinfo->TI.scaler_period = evdata->GetRawData(ip++);
cinfo->TI.sync_count = evdata->GetRawData(ip++);
} else {
cinfo->TI.scaler_period = 2;
cinfo->TI.sync_count = -1;
}
for(Int_t i = 0; i<cinfo->TI.num_prescales; i++) {
cinfo->TI.prescales[i] = evdata->GetRawData(ip++);
}
UInt_t lastword = evdata->GetRawData(ip++);
if(lastword != 0xd000000f) {
cout << "Unexpected last word of TI information block "
<< hex << lastword << dec << endl;
}
}
} else {
cout << "Expected header missing" << endl;
cout << ip << " " << hex << thisword << dec << endl;
ip = evlen;
}
}
//cout << "Making Parms for ROC " << roc << " Event type " << evdata->GetEvType() << endl;
_logger->info("Making Parms for ROC {} Event type ", roc, evdata->GetEvType());
MakeParms(roc);
return 1;
}
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
void THcConfigEvtHandler::MakeParms(Int_t roc)
{
/**
Add parameters to gHcParms for this roc
*/
std::map<Int_t, CrateInfo_t *>::iterator it = CrateInfoMap.begin();
while(it != CrateInfoMap.end()) {
Int_t thisroc = it->first;
if(thisroc != roc) {
it++;
continue;
}
CrateInfo_t *cinfo = it->second;
// CAEN 1190 TDC information
if (cinfo->CAEN1190.present) {
Int_t resolution = cinfo->CAEN1190.resolution;
gHcParms->Define(Form("g%s_tdc_resolution_%d",fName.Data(),roc),"TDC resolution",resolution);
Int_t offset = cinfo->CAEN1190.timewindow_offset;
gHcParms->Define(Form("g%s_tdc_offset_%d",fName.Data(),roc),"TDC Time Window Offset",offset);
Int_t width = cinfo->CAEN1190.timewindow_width;
gHcParms->Define(Form("g%s_tdc_width_%d",fName.Data(),roc),"TDC Time Window Width",width);
}
// FADC Thresholds
if (cinfo->FADC250.present) {
// Loop over FADC slots
std::map<Int_t, Int_t *>::iterator itt = cinfo->FADC250.thresholds.begin();
while(itt != cinfo->FADC250.thresholds.end()) {
Int_t slot = itt->first;
// this memory would leak
// Int_t *thresholds = new Int_t[16];
// memcpy(thresholds,itt->second,16*sizeof(Int_t));
// gHcParms->Define(Form("g%s_adc_thresholds_%d_%d[16]",fName.Data(),roc,slot),"ADC Thresholds",*thresholds);
// Define the variable directly on the CrateInfo_t that resides in CrateInfoMap where it will stay
// until the end of the life of this object
gHcParms->Define(Form("g%s_adc_thresholds_%d_%d[16]",fName.Data(),roc,slot),"ADC Thresholds",*itt->second);
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
Int_t mode = cinfo->FADC250.mode;
gHcParms->Define(Form("g%s_adc_mode_%d_%d",fName.Data(),roc,slot),"ADC Mode",mode);
Int_t latency = cinfo->FADC250.window_lat;
gHcParms->Define(Form("g%s_adc_latency_%d_%d",fName.Data(),roc,slot),"Window Latency",latency);
Int_t width = cinfo->FADC250.window_width;
gHcParms->Define(Form("g%s_adc_width_%d_%d",fName.Data(),roc,slot),"Window Width",width);
Int_t daclevel = cinfo->FADC250.dac_level;
gHcParms->Define(Form("g%s_adc_daclevely_%d_%d",fName.Data(),roc,slot),"DAC Level",daclevel);
Int_t nped = cinfo->FADC250.nped;
gHcParms->Define(Form("g%s_adc_nped_%d_%d",fName.Data(),roc,slot),"NPED",nped);
Int_t nsa = cinfo->FADC250.nsa;
gHcParms->Define(Form("g%s_adc_nsa_%d_%d",fName.Data(),roc,slot),"NSA",nsa);
Int_t maxped = cinfo->FADC250.maxped;
gHcParms->Define(Form("g%s_adc_maxped_%d_%d",fName.Data(),roc,slot),"MAXPED",maxped);
Int_t np = cinfo->FADC250.np;
gHcParms->Define(Form("g%s_adc_np_%d_%d",fName.Data(),roc,slot),"NP",np);
itt++;
}
// TI Configuration
// We assume that this information is only provided by the master TI crate.
// If that is not true we will get "Variable XXX already exists." warnings
if(cinfo->TI.present) {
Int_t nped = cinfo->TI.nped;
gHcParms->Define(Form("g%s_ti_nped",fName.Data()),"Number of Pedestal events",nped);
Int_t scaler_period = cinfo->TI.scaler_period;
gHcParms->Define(Form("g%s_ti_scaler_period",fName.Data()),"Number of Pedestal events",scaler_period);
Int_t sync_count = cinfo->TI.sync_count;
gHcParms->Define(Form("g%s_ti_sync_count",fName.Data()),"Number of Pedestal events",sync_count);
Int_t *ps_exps = new Int_t[cinfo->TI.num_prescales];
Int_t *ps_factors = new Int_t[cinfo->TI.num_prescales];
for(Int_t i=0;i<cinfo->TI.num_prescales;i++) {
ps_exps[i] = cinfo->TI.prescales[i];
if(ps_exps[i] > 0) {
ps_factors[i] = (1<<(ps_exps[i]-1)) + 1;
} else if (ps_exps[i] == 0) {
ps_factors[i] = 1;
} else {
ps_factors[i] = -1;
}
gHcParms->Define(Form("g%s_ti_ps[%d]",fName.Data(),cinfo->TI.num_prescales),"TI Event Prescale Internal Value",*ps_exps);
gHcParms->Define(Form("g%s_ti_ps_factors[%d]",fName.Data(),cinfo->TI.num_prescales),"TI Event Prescale Factor",*ps_factors);
}
}
it++;
}
}
void THcConfigEvtHandler::PrintConfig()
{
/**
Stub of method to pretty print the config data
*/
std::map<Int_t, CrateInfo_t *>::iterator it = CrateInfoMap.begin();
while(it != CrateInfoMap.end()) {
Int_t roc = it->first;
cout << "================= Configuration Data ROC " << roc << "==================" << endl;
CrateInfo_t *cinfo = it->second;
if(cinfo->CAEN1190.present) {
cout << " CAEN 1190 Configuration" << endl;
cout << " Resolution: " << cinfo->CAEN1190.resolution << " ps" << endl;
cout << " T Offset: " << cinfo->CAEN1190.timewindow_offset << endl;
cout << " T Width: " << cinfo->CAEN1190.timewindow_width << endl;
}
if (cinfo->FADC250.present) {
cout << " FADC250 Configuration" << endl;
cout << " Mode: " << cinfo->FADC250.mode << endl;
cout << " Latency: " << cinfo->FADC250.window_lat << " Width: "<< cinfo->FADC250.window_width << endl;
cout << " DAC Level: " << cinfo->FADC250.dac_level << " Threshold: " << cinfo->FADC250.threshold << endl;
cout << " NPED: " << cinfo->FADC250.nped << " NSA: " << cinfo->FADC250.nsa << " NSB: " << cinfo->FADC250.nsb << endl;
cout << " MAXPED: " << cinfo->FADC250.maxped << " NP: " << cinfo->FADC250.np << " NSAT: " << cinfo->FADC250.nsat << endl;
// Loop over FADC slots
cout << " Thresholds";
std::map<Int_t, Int_t *>::iterator itt = cinfo->FADC250.thresholds.begin();
while(itt != cinfo->FADC250.thresholds.end()) {
Int_t slot = itt->first;
cout << " " << setw(5) << slot;
itt++;
}
cout << endl;
for(Int_t ichan=0;ichan<16;ichan++) {
cout << " " << setw(2) << ichan << " ";
std::map<Int_t, Int_t *>::iterator itt = cinfo->FADC250.thresholds.begin();
while(itt != cinfo->FADC250.thresholds.end()) {
Int_t *thresholds = itt->second;
cout << " " << setw(5) << thresholds[ichan];
itt++;
}
cout << endl;
}
}
if(cinfo->TI.present) {
cout << " TI Configuration" << endl;
cout << " N Pedestals: " << cinfo->TI.nped << " events" << endl;
cout << " Scaler Period: " << cinfo->TI.scaler_period << " seconds" << endl;
cout << " Sync interval: " << cinfo->TI.sync_count << " events" << endl;
cout << " Prescales: ";
for(Int_t i=0;i<cinfo->TI.num_prescales;i++) {
cout << " " << cinfo->TI.prescales[i];
}
cout << endl;
}
Int_t THcConfigEvtHandler::IsPresent(Int_t crate) {
if(CrateInfoMap.find(crate)!=CrateInfoMap.end()) {
CrateInfo_t *cinfo = CrateInfoMap[crate];
return cinfo->FADC250.present;
}
return(0);
}
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
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)
{
_logger->info("Howdy ! We are initializing THcConfigEvtHandler !! name = {}",fName.Data());
if(eventtypes.size()==0) {
eventtypes.push_back(125); // what events to look for
}
DeleteCrateInfoMap();
fStatus = kOK;
return kOK;
}
ClassImp(THcConfigEvtHandler)