Commit ef7feeb4 authored by Georg Auzinger's avatar Georg Auzinger
Browse files

merged recent Dev branch changes into Pulseshape to facilitate feature merge in Dev

parents e86a4ed8 1b2a9956
......@@ -5,3 +5,9 @@ latex/*
html/*
html/
latex/
*.bin
*.raw
Results/*
settings/connections_slc6.xml
# just for G. Auzingers sanity
CalibrationResults
all: Utils HWDescription HWInterface System tools src GUI
all: Utils HWDescription HWInterface System tools RootWeb src miniDAQ
libs: Utils HWDescription HWInterface System srcnoroot
gui: Utils HWDescription HWInterface System tools src GUI
gui: Utils HWDescription HWInterface System tools src miniDAQ GUI
simple: Utils HWDescription HWInterface System tools src
simple: Utils HWDescription HWInterface System tools RootWeb src miniDAQ
HWDescription::
$(MAKE) -C $@
......@@ -24,6 +24,10 @@ GUI::
$(MAKE) -C GUI/Macros
$(MAKE) -C $@
cp $@/Ph2_ACF ./bin
RootWeb::
$(MAKE) -C $@
miniDAQ::
$(MAKE) -C $@
doc::
$(MAKE) -C $@
......@@ -34,6 +38,8 @@ clean:
(cd HWInterface; make clean)
(cd HWDescription; make clean)
(cd tools; make clean)
(cd RootWeb; make clean)
(cd miniDAQ; make clean)
(cd GUI; make clean)
(cd GUI; make clean; cd GUI/Macros; make clean)
(cd doc; make clean)
......
......@@ -78,6 +78,13 @@ On this Repo, you can find different version of the software :
- Data class now holds a vector of Events and the events are directly decoded after acquisition - the char* databuffer does not exist any longer
- added methods: std::vector<Event*> GetEvents(); Event* GetEvent()
- updated all scripts
- 17/07/2015: including a new executable flashfpga to upload .mcs files to the EPROM, updated tool base-class, included DQM code from the Beamtest
- fpgaconfig binary allows to upload FW images to EPROM (2 separate images)
- tool base class now contains containers for histograms along with bookHisto(), getHisto(), saveHisto() methods
- modified all other tools accordingly
- merged the DQM code from the June '15 beamtest into miniDQM binary
- updated Makefiles to build RootWeb & miniDQM
- 04/08/2015: adding a faster & more precise algorithm to extract the parameters from SCurves via differentiating it
......
......@@ -2,21 +2,17 @@ ROOTFLAGS=`root-config --cflags`
ROOTLIBDIR=`root-config --libdir`
ROOTLIBFLAGS=`root-config --libs`
ROOTLIBFLAGS+=-lHistPainter
ifneq ($(strip $(BOOST_INCLUDE)),)
INCLUDEFLAGS=-I$(BOOST_INCLUDE)
endif
ifneq ($(strip $(BOOST_LIB)),)
BOOSTLIBFLAGS=-L$(BOOST_LIB)
endif
BOOSTLIBFLAGS+=-L$(BOOST_LIB) -lboost_system$(BOOST_SUFFIX) -lboost_filesystem$(BOOST_SUFFIX) -lboost_program_options$(BOOST_SUFFIX)
GEOMLIBFLAG=-lGeom
GLIBFLAGS=`root-config --glibs`
INCLUDEFLAGS+=-Iinclude/
SRCDIR=src
INCDIR=include
LIBDIR=lib
BINDIR=bin
TESTDIR=test
# BINDIR=bin
# TESTDIR=test
COMPILERFLAGS+=-std=c++11
COMPILERFLAGS+=-g -fPIC
COMPILERFLAGS+=-fpermissive
......
#include "rootweb.hh"
#include <string>
class TH1D;
namespace RootWeb {
void makePageOne(RootWSite& site);
TH1D* createPlot();
void makePageTwo(RootWSite& site, const std::string& inFilename );
void prepareSiteStuff(RootWSite& site, const std::string& run);
void makeDQMmonitor(const std::string& inFilename, const std::string& run);
namespace RootWeb
{
void makePageOne( RootWSite& site );
TH1D* createPlot();
void makePageTwo( RootWSite& site, const std::string& inFilename );
void prepareSiteStuff( RootWSite& site, std::string& directory, const std::string& run );
void makeDQMmonitor( const std::string& inFilename, std::string& directory, const std::string& run );
}
......@@ -7,118 +7,128 @@
#include "TDirectory.h"
#include "publisher.h"
namespace RootWeb {
void makePageOne(RootWSite& site) {
// Adding one page
auto& home = site.addPage("Home");
home.setAddress("index.html");
namespace RootWeb
{
void makePageOne( RootWSite& site )
{
// Adding one page
auto& home = site.addPage( "Home" );
home.setAddress( "index.html" );
#if 0
// With one collapsing content (default is open)
auto& content1 = home.addContent("Section 1");
// With a table of strings
auto& aTableS = content1.addTable();
for (int i=1; i<=10; ++i) {
for (int j=1; j<=10; ++j) {
aTableS.setContent(i, j, Form("G%d", i*j));
}
}
// With a table of doubles (3 decimal places)
auto& aTableD = content1.addTable();
for (int i=1; i<=10; ++i) {
for (int j=1; j<=10; ++j) {
aTableD.setContent(i, j, sqrt(i*j), 3);
}
}
// The second content is collapsed by defauls
auto& content2 = home.addContent("Section 2", false);
content2.addText("Hello, there, I was hiding here");
// With one collapsing content (default is open)
auto& content1 = home.addContent( "Section 1" );
// With a table of strings
auto& aTableS = content1.addTable();
for ( int i = 1; i <= 10; ++i )
{
for ( int j = 1; j <= 10; ++j )
aTableS.setContent( i, j, Form( "G%d", i * j ) );
}
// With a table of doubles (3 decimal places)
auto& aTableD = content1.addTable();
for ( int i = 1; i <= 10; ++i )
{
for ( int j = 1; j <= 10; ++j )
aTableD.setContent( i, j, sqrt( i * j ), 3 );
}
// The second content is collapsed by defauls
auto& content2 = home.addContent( "Section 2", false );
content2.addText( "Hello, there, I was hiding here" );
#endif
}
TH1D* createPlot() {
TH1D* myHisto = new TH1D("test", "Here I am", 10, 0, 10);
myHisto->Fill(3);
myHisto->Fill(3);
myHisto->Fill(4);
myHisto->Fill(5);
return myHisto;
}
void makePageTwo(RootWSite& site, const std::string& inFilename ) {
auto& myPage = site.addPage("DQM Plots");
}
// With a content containing some plots
auto& content1 = myPage.addContent("Common Plots");
// open DQM file
TFile* fin = TFile::Open(TString(inFilename));
std::vector<TKey*> directoryKey;
TIter next(fin->GetListOfKeys());
TObject *obj;
// Header etc.
while ((obj = next())) {
TKey *key = dynamic_cast<TKey*>(obj);
TClass *cl = gROOT->GetClass(key->GetClassName());
if ( cl->InheritsFrom("TDirectory") )
directoryKey.push_back(key);
else if ( cl->InheritsFrom("TH1") ) {
TH1* h = dynamic_cast<TH1*>(key->ReadObj());
h->SetDirectory(0);
TString canvasName("c" + std::string(key->GetName()));
TCanvas* myCanvas = new TCanvas( canvasName, "c1", 500, 500);
myCanvas->cd();
h->Draw();
auto& myImage = content1.addImage(myCanvas, 600, 400);
myImage.setComment("A little explanation here always helps");
myImage.setName(h->GetTitle());
}
}
std::cout << "DirKeyVec size=" << directoryKey.size() << std::endl;
TH1D* createPlot()
{
TH1D* myHisto = new TH1D( "test", "Here I am", 10, 0, 10 );
myHisto->Fill( 3 );
myHisto->Fill( 3 );
myHisto->Fill( 4 );
myHisto->Fill( 5 );
return myHisto;
}
// CBC Plots
for ( auto& key: directoryKey ) {
auto& content2 = myPage.addContent("Plots for " + std::string(key->GetName()) );
TDirectory* dir = dynamic_cast<TDirectory*>(key->ReadObj());
TIter next(dir->GetListOfKeys());
TKey *hkey;
while ((hkey = (TKey*)next())) {
TClass *cl = gROOT->GetClass(hkey->GetClassName());
if (!cl->InheritsFrom("TH1")) continue;
TH1* h = dynamic_cast<TH1*>(hkey->ReadObj());
h->SetDirectory(0);
TString canvasName("c" + std::string(hkey->GetName()));
TCanvas* myCanvas = new TCanvas( canvasName, "c1", 500, 500);
myCanvas->cd();
h->Draw();
auto& myImage = content2.addImage(myCanvas, 600, 400);
myImage.setComment("A little explanation here always helps");
myImage.setName(h->GetTitle());
}
}
fin->Close();
void makePageTwo( RootWSite& site, const std::string& inFilename )
{
auto& myPage = site.addPage( "DQM Plots" );
auto& content3 = myPage.addContent("All plots here");
content3.addBinaryFile(inFilename, "content of all your plots is here", inFilename);
}
void prepareSiteStuff(RootWSite& site, const std::string& run) {
std::string myDirectory="/afs/cern.ch/work/m/mersi/Ph2BeamTest/"+run;
site.setTargetDirectory(myDirectory);
site.setTitle(run);
site.setComment("Complete run list");
site.setCommentLink("../");
site.addAuthor("Mickey Mouse");
site.addAuthor("Dylan Dog");
site.addAuthor("Nathan Never");
site.setRevision("0.1");
site.setProgram("Ph2_DAQ", "https://github.com/gauzinge/Ph2_ACF");
}
void makeDQMmonitor(const std::string& inFilename, const std::string& run) {
RootWSite site;
prepareSiteStuff(site,run);
makePageOne(site);
makePageTwo(site,inFilename);
site.makeSite(false);
}
// With a content containing some plots
auto& content1 = myPage.addContent( "Common Plots" );
// open DQM file
TFile* fin = TFile::Open( TString( inFilename ) );
std::vector<TKey*> directoryKey;
TIter next( fin->GetListOfKeys() );
TObject* obj;
// Header etc.
while ( ( obj = next() ) )
{
TKey* key = dynamic_cast<TKey*>( obj );
TClass* cl = gROOT->GetClass( key->GetClassName() );
if ( cl->InheritsFrom( "TDirectory" ) )
directoryKey.push_back( key );
else if ( cl->InheritsFrom( "TH1" ) )
{
TH1* h = dynamic_cast<TH1*>( key->ReadObj() );
h->SetDirectory( 0 );
TString canvasName( "c" + std::string( key->GetName() ) );
TCanvas* myCanvas = new TCanvas( canvasName, "c1", 500, 500 );
myCanvas->cd();
h->Draw();
auto& myImage = content1.addImage( myCanvas, 600, 400 );
myImage.setComment( "A little explanation here always helps" );
myImage.setName( h->GetTitle() );
}
}
std::cout << "DirKeyVec size=" << directoryKey.size() << std::endl;
// CBC Plots
for ( auto& key : directoryKey )
{
auto& content2 = myPage.addContent( "Plots for " + std::string( key->GetName() ) );
TDirectory* dir = dynamic_cast<TDirectory*>( key->ReadObj() );
TIter next( dir->GetListOfKeys() );
TKey* hkey;
while ( ( hkey = ( TKey* )next() ) )
{
TClass* cl = gROOT->GetClass( hkey->GetClassName() );
if ( !cl->InheritsFrom( "TH1" ) ) continue;
TH1* h = dynamic_cast<TH1*>( hkey->ReadObj() );
h->SetDirectory( 0 );
TString canvasName( "c" + std::string( hkey->GetName() ) );
TCanvas* myCanvas = new TCanvas( canvasName, "c1", 500, 500 );
myCanvas->cd();
h->Draw();
auto& myImage = content2.addImage( myCanvas, 600, 400 );
myImage.setComment( "A little explanation here always helps" );
myImage.setName( h->GetTitle() );
}
}
fin->Close();
auto& content3 = myPage.addContent( "All plots here" );
content3.addBinaryFile( inFilename, "content of all your plots is here", inFilename );
}
void prepareSiteStuff( RootWSite& site, std::string& directory, const std::string& run )
{
directory += run;
site.setTargetDirectory( directory );
site.setTitle( run );
site.setComment( "Complete run list" );
site.setCommentLink( "../" );
site.addAuthor( "Mickey Mouse" );
site.addAuthor( "Dylan Dog" );
site.addAuthor( "Nathan Never" );
site.setRevision( "0.1" );
site.setProgram( "Ph2_DAQ", "https://github.com/gauzinge/Ph2_ACF" );
}
void makeDQMmonitor( const std::string& inFilename, std::string& directory, const std::string& run )
{
RootWSite site;
prepareSiteStuff( site, directory, run );
makePageOne( site );
makePageTwo( site, inFilename );
site.makeSite( false );
}
}
*
!*.*
\ No newline at end of file
CC = gcc
CXX = g++
CCFlags = -g -O1 -w -Wall -pedantic -std=c++11 -fPIC
CCFlagsRoot = `root-config --cflags --evelibs --glibs`
#DevFlags = -D__CBCDAQ_DEV__
DevFlags =
IncludeDirs = /opt/cactus/include ../
IncludePaths = $(IncludeDirs:%=-I%)
LibraryDirs = /opt/cactus/lib ../lib
# /opt/xdaq/lib
LibraryPaths = $(LibraryDirs:%=-L%)
ExternalObjects= $(LibraryPaths) -lpthread -lcactus_extern_pugixml -lcactus_uhal_log -lcactus_uhal_grammars -lcactus_uhal_uhal -lboost_system -lPh2_Interface -lPh2_Description -lPh2_System -lPh2_Utils -lboost_filesystem -lboost_program_options -L../RootWeb/lib -lRootWeb
# ExtObjectsRoot= -lPh2_Tools
# %.o: %.cc %.h
# $(CXX) -std=c++11 $(DevFlags) $(CCFlags) $(UserCCFlags) $(CCDefines) $(IncludePaths) -c -o $@ $<
binaries=miniDQM
all: rootflags clean $(binaries)
rootflags:
$(eval CCFlags += $(CCFlagsRoot))
$(eval ExternalObjects += $(ExtObjectsRoot))
miniDQM: datatestFromfile.cc
$(CXX) -std=c++11 $(CCFlags) -o $@ $< $(IncludePaths) $(ExternalObjects)
cp $@ ../bin
.PHONY: clean
clean:
rm -f $(binaries) *.o
#include <cstring>
#include <stdint.h>
#include <iostream>
#include <string>
#include <fstream>
#include <map>
#include <sstream>
#include <inttypes.h>
#include "../Utils/Utilities.h"
#include "../Utils/Data.h"
#include "../Utils/Event.h"
#include "../Utils/Timer.h"
#include "../Utils/argvparser.h"
#include "../Utils/ConsoleColor.h"
#include "../System/SystemController.h"
#include "../RootWeb/include/publisher.h"
#include "TROOT.h"
#include "TH1.h"
#include "TFile.h"
#include "TString.h"
using namespace Ph2_HwDescription;
using namespace Ph2_HwInterface;
using namespace Ph2_System;
using namespace CommandLineProcessing;
void tokenize( const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters )
{
// Skip delimiters at beginning.
std::string::size_type lastPos = str.find_first_not_of( delimiters, 0 );
// Find first "non-delimiter".
std::string::size_type pos = str.find_first_of( delimiters, lastPos );
while ( std::string::npos != pos || std::string::npos != lastPos )
{
// Found a token, add it to the vector.
tokens.push_back( str.substr( lastPos, pos - lastPos ) );
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of( delimiters, pos );
// Find next "non-delimiter"
pos = str.find_first_of( delimiters, lastPos );
}
}
void readDataFile( const std::string infile, std::vector<uint32_t>& list )
{
uint32_t word;
std::ifstream fin( infile, std::ios::in | std::ios::binary );
if ( fin.is_open() )
{
while ( !fin.eof() )
{
char buffer[4];
fin.read( buffer, 4 );
uint32_t word;
memcpy( &word, buffer, 4 );
list.push_back( word );
}
fin.close();
}
else
std::cerr << "Failed to open " << infile << "!" << std::endl;
}
void fillDQMhisto( const std::vector<Event*>& elist, const std::string& outFileName )
{
std::map<std::string, TH1I*> herrbitmap;
std::map<std::string, TH1I*> hnstubsmap;
std::map<std::string, std::vector<TH1I*>> hchdatamap;
TH1I* hl1A = new TH1I( "l1A", "L1A Counter", 10000, 0, 10000 );
TH1I* htdc = new TH1I( "tdc", "TDC counter", 256, -0.5, 255.5 );
for ( const auto& ev : elist )
{
htdc->Fill( ev->GetTDC() );
hl1A->Fill( ev->GetEventCount() );
const EventMap& evmap = ev->GetEventMap();
for ( auto const& it : evmap )
{
uint32_t feId = it.first;
for ( auto const& jt : it.second )
{
uint32_t cbcId = jt.first;
// create histogram name tags
std::stringstream ss;
ss << "fed" << feId << "cbc" << cbcId;
std::string key = ss.str();
// Error bit histogram
if ( herrbitmap.find( key ) == herrbitmap.end() )
herrbitmap[key] = new TH1I( TString( "errbit" + key ), "Error bit", 3, -0.5, 2.5 );
herrbitmap[key]->Fill( static_cast<int>( ev->Error( feId, cbcId ) ) );
// #Stubs info
int nstubs = std::stoi( ev->StubBitString( feId, cbcId ), nullptr, 10 );
if ( hnstubsmap.find( key ) == hnstubsmap.end() )
hnstubsmap[key] = new TH1I( TString( "nstubs" + key ), "Number of stubs", 21, -0.5, 20.5 );
hnstubsmap[key]->Fill( nstubs );
// channel data
const std::vector<bool>& dataVec = ev->DataBitVector( feId, cbcId );
if ( hchdatamap.find( key ) == hchdatamap.end() )
{
hchdatamap[key].push_back( new TH1I( TString( "chOccupancy_even" + key ), "Even channel occupancy", 127, 0.5, 127.5 ) );
hchdatamap[key].push_back( new TH1I( TString( "chOccupancy_odd" + key ), "Odd channel occupancy", 127, 0.5, 127.5 ) );
}
for ( unsigned int ch = 0; ch < dataVec.size(); ch++ )
{
if ( dataVec[ch] )
{
if ( ch % 2 == 0 )
hchdatamap[key][0]->Fill( ch / 2 + 1 );
else
hchdatamap[key][1]->Fill( ch / 2 + 1 );
}
}
}
}
}
TFile* fout = TFile::Open( outFileName.c_str(), "RECREATE" );
for ( auto& he : herrbitmap )
{
fout->mkdir( he.first.c_str() );
fout->cd( he.first.c_str() );
he.second->Write();
}
for ( auto& he : hnstubsmap )
{
fout->cd( he.first.c_str() );
he.second->Write();
}
for ( auto& hVec : hchdatamap )
{
fout->cd( hVec.first.c_str() );
hVec.second.at( 0 )->Write();
hVec.second.at( 1 )->Write();
}
fout->cd();
hl1A->Write();
htdc->Write();
fout->Close();
}
void dumpEvents( const std::vector<Event*>& elist )
{
for ( int i = 0; i < elist.size(); i++ )
{
std::cout << "Event index: " << i << std::endl;
std::cout << *elist[i] << std::endl;
}
}
int main( int argc, char* argv[] )
{
ArgvParser cmd;
// init
cmd.setIntroductoryDescription( "CMS Ph2_ACF miniDQM application" );
// error codes
cmd.addErrorCode( 0, "Success" );
cmd.addErrorCode( 1, "Error" );
// options
cmd.setHelpOption( "h", "help", "Print this help page" );
cmd.defineOption( "file", "Binary Data File", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ );
cmd.defineOptionAlternative( "file", "f" );
cmd.defineOption( "output", "Output Directory for DQM plots & page. Default value: Results", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ );
cmd.defineOptionAlternative( "output", "o" );
cmd.defineOption( "dqm", "Build DQM webpage. Default = false", ArgvParser::NoOptionAttribute /*| ArgvParser::OptionRequired*/ );
cmd.defineOptionAlternative( "dqm", "d" );
cmd.defineOption( "swap", "Swap endianness in Data::set. Default = true (Ph2_ACF); should be false for GlibStreamer Data", ArgvParser::NoOptionAttribute /*| ArgvParser::OptionRequired*/ );
cmd.defineOptionAlternative( "swap", "s" );
int result = cmd.parse( argc, argv );
if ( result != ArgvParser::NoParserError )
{
std::cout << cmd.parseErrorDescription( result );
exit( 1 );
}
// now query the parsing results
std::string rawFilename = ( cmd.foundOption( "file" ) ) ? cmd.optionValue( "file" ) : "";
if ( rawFilename.empty() )
{
std::cerr << "Error, no binary file provided. Quitting" << std::endl;
exit( 1 );
}
bool cSwap = ( cmd.foundOption( "swap" ) ) ? false : true;
bool cDQMPage = ( cmd.foundOption( "dqm" ) ) ? true : false;
std::string cDirBasePath;
if ( cDQMPage )
{
if ( cmd.foundOption( "output" ) )
{
cDirBasePath = cmd.optionValue( "output" );
cDirBasePath += "/";
}
else cDirBasePath = "Results/";
}
else std::cout << "Not creating DQM files!" << std::endl;