Commit ea98d923 authored by dino's avatar dino
Browse files

Added event_tstdiff.bdat and time-stamp difference spectrum in CrystalProducer.

Modified GridSearchClasses.h to avoid memory alignment if not using SSE instructions.

git-svn-id: svn://gal-serv.lnl.infn.it/agata/trunk/narval_emulator@1115 170316e4-aea8-4b27-aad4-0380ec0519c9
parent 738d209a
......@@ -23,9 +23,12 @@ MESSAGE("Boost Dirs: ${Boost_INCLUDE_DIR} ${Boost_LIBRARY_DIRS}")
SET(BOOST_LIBRARIES "-L${Boost_LIBRARY_DIRS} -l:libboost_system.a -l:libboost_thread.a")
MESSAGE("Boost Libs: ${BOOST_LIBRARIES}")
# Enable the vectorized version of the PSA FOM-loop
# For the vectorized version of the PSA FOM-loop
#ADD_DEFINITIONS(-DUSE_SSE_VERSION)
set(CMAKE_CXX_FLAGS "-msse4")
IF(USE_SSE_VERSION)
SET(CMAKE_CXX_FLAGS "-msse4")
MESSAGE("USE_SSE_VERSION is defined")
ENDIF()
# The sources to build femul
SET(AGADIR "../..")
......@@ -137,8 +140,8 @@ ${ADFDIR}/standalone/CentralLog.cpp
${ADFDIR}/standalone/LogCollector.cpp
${ADFDIR}/standalone/LogMessage.cpp
${ADFDIR}/BasicAFC.cpp
${ADFDIR}/BasicAFP.cpp
${ADFDIR}/DefaultFrameFactory.cpp
${ADFDIR}/BasicAFP.cpp
${ADFDIR}/DefaultFrameFactory.cpp
)
SET(PRISMA_SRCS
......
......@@ -82,8 +82,14 @@ PSAFilterGridSearch::PSAFilterGridSearch()
hmask[nn][INDCC+1] = 0; // +1 to close each line as a string
}
for(int nn = 0; nn < 37; nn++)
tauSGCC[nn] = tauDefault;
memset(tauSGCC, 0, sizeof(tauSGCC));
//for(int nn = 0; nn < 37; nn++)
// tauSGCC[nn] = tauDefault;
// re-written in this funny way due to core dump in i486 Ubuntu ??
tauSGCC[NSEGS] = tauDefault;
for(int nn = 0; nn < NSEGS; nn++) {
tauSGCC[nn] = tauSGCC[NSEGS];
}
#ifdef PSA_MULTIHIST
PsaSpecEner = NULL; PsaSpecStat = NULL; PsaSpecTZero = NULL; PsaSpecSigma = NULL; PsaSpecMetric = NULL;
......
......@@ -83,7 +83,7 @@ private:
bool firstEventPSA;
float tauSGCC[37]; // the 36 segments and the CC
float tauSGCC[NSEGS+4]; // the 36 segments and the CC (and some spare)
#ifdef PSA_MULTIHIST
MultiHist<unsigned int > *PsaSpecEner;
......
......@@ -7,13 +7,15 @@
#include <cmath>
#include <string.h>
#ifndef MEMALIGN_16
#ifndef USE_SSE_VERSION
# define GS_MEMALIGN_16
#else
# if defined(__GNUC__)
# define MEMALIGN_16 __attribute__((aligned(16)))
# define GS_MEMALIGN_16 __attribute__((aligned(16)))
# elif defined(_MSC_VER)
# define MEMALIGN_16 __declspec(align(16))
# define GS_MEMALIGN_16 __declspec(align(16))
# else
# define MEMALIGN_16
# define GS_MEMALIGN_16
# endif
#endif
......@@ -43,8 +45,8 @@ class pointPsa
public:
float x, y, z; // coordinates of the interaction (mm)
int netChargeSegment; // its net-charge segment
MEMALIGN_16 // compiler-specific alignment directive
float amplitude[TCHAN][NTIME]; // 36 segments + CC + non differentiated copies of net-charge segment and the core
GS_MEMALIGN_16 // compiler-specific alignment directive
float amplitude[TCHAN][NTIME]; // 36 segments + CC + non differentiated copies of net-charge segment and the core
int addr_first; // valid/useful start of the amplitude
int addr_last; // valid/useful last of the amplitude (margin included)
float sumTransients; // sum of all transient signals
......@@ -406,14 +408,14 @@ public:
int numNetCharges;
int netChargeSegnum[NSEGS]; // normally given in the order of energy release
float netChargeEnergy[NSEGS];
MEMALIGN_16
float tAmplitude[TCHAN][NTIME]; // the total original experimental data
MEMALIGN_16
float wAmplitude[TCHAN][NTIME]; // the experimental data to be used and modified by the grid search
MEMALIGN_16
float sAmplitude[TCHAN][NTIME]; // experimental trace manipulated for being used by the "chi2" loops
MEMALIGN_16
float rAmplitude[TCHAN][NTIME]; // the "fitted" trace
GS_MEMALIGN_16
float tAmplitude[TCHAN][NTIME]; // the total original experimental data
GS_MEMALIGN_16
float wAmplitude[TCHAN][NTIME]; // the experimental data to be used and modified by the grid search
GS_MEMALIGN_16
float sAmplitude[TCHAN][NTIME]; // experimental trace manipulated for being used by the "chi2" loops
GS_MEMALIGN_16
float rAmplitude[TCHAN][NTIME]; // the "fitted" trace
int resPt1[NSEGS]; // the best 1st solution point for the numNetCharges segments
int resPt2[NSEGS]; // the best 2nd solution point "
......
......@@ -50,7 +50,7 @@ protected:
std::string fOdirPrefix;
Long64_t fTstampCorr;
UInt_t fWriteDataMask; // 0=none, 1=input_mezzdata[], 2=event_mezzdata 4=event_mezzhead 8=event_energy 16=event_core
UInt_t fWriteDataMask; // 0=none, 1=input_mezzdata[], 2=event_mezzdata 4=event_mezzhead 8=event_energy 16=event_core, 32=event_tstdiff
UInt_t fDecimateMezzData; // write one every fDecimateMezzData
UInt_t fDecimateMezzEner; // write one every fDecimateMezzEner
Int_t fWriteDataMinAmpl; // event written to event_mezzdata.bdat only if CC[0] amplitude > fWriteDataThreshold
......
......@@ -51,6 +51,8 @@ using namespace ADF;
const int specLenE = 32*1024;
const int rangeADC = 1<<14;
const int tStampBuffSize = 2048;
CrystalProducerATCA::CrystalProducerATCA():
DAQ_NFILE(0), DAQ_NMEZZ(0), ANA_NSEGS(0),
FA(NULL), MZ(NULL), CC(NULL), PR(NULL), mezzFound(NULL), mezzToGet(0),
......@@ -58,7 +60,7 @@ nfiles(0), fnstep(1), bReaFromFile(false),
maxDiff(0), expDiff(0), bStartCalled(false),
bSync(true), bStatistics(false),
tStamp(NULL), tDelta(NULL), eEvnum(NULL), eDelta(NULL), Number(NULL), evLost(NULL),
tStampErr(0), tStampNew(0)
tStampErr(0), tStampNew(0), tStampOld(0)
{
memset(wFp, 0, sizeof(wFp));
memset(wWritten, 0, sizeof(wWritten));
......@@ -68,11 +70,16 @@ tStampErr(0), tStampNew(0)
library_timeout = 0;
fpProdTstampDiff = NULL;
fProdTstampDiffBuff = NULL;
fProdTstampDiffCount = 0;
fUseMultiHist = true;
#ifdef CRP_MULTIHIST
ProdSpec_Ampl = NULL;
ProdSpec_Base = NULL;
ProdSpec_Rate = NULL;
ProdSpec_Tstd = NULL;
#endif //CRP_MULTIHIST
};
......@@ -80,6 +87,16 @@ CrystalProducerATCA::~CrystalProducerATCA()
{
cServer.Finish();
if(doWriteTstampDiff) {
if(fpProdTstampDiff) {
if(fProdTstampDiffCount)
fwrite(fProdTstampDiffBuff, sizeof(UInt_t), fProdTstampDiffCount, fpProdTstampDiff);
fclose(fpProdTstampDiff);
}
}
if(fProdTstampDiffBuff)
delete [] fProdTstampDiffBuff;
for(int nn = 0; nn < CrystalInterface::kNbSegments; nn++ )
delete [] SegmentTraces[nn];
for(int nn = 0; nn < CrystalInterface::kNbCores; nn++ )
......@@ -135,7 +152,10 @@ Int_t CrystalProducerATCA::AlgoSpecificInitialise()
return 111;
}
if(!InitATCA(fWriteDataMask, (fWriteDataSplit<INT_MAX)?fWriteDataSplit:0) ) {
writeDataMask = fWriteDataMask;
writeDataSplit = (fWriteDataSplit<INT_MAX)?fWriteDataSplit:0;
if(!InitATCA(writeDataMask&1)) {
return 120;
}
......@@ -195,6 +215,10 @@ Int_t CrystalProducerATCA::AlgoSpecificInitialise()
//ProdSpec_Rate->setFileName(fOdirPrefix+"Prod?Rate.spec");
//ProdSpec_Rate->setComment("Counting rate of the core");
//hGroup.add(ProdSpec_Rate);
ProdSpec_Tstd = new MultiHist<unsigned int>(100000);
ProdSpec_Tstd->setFileName(fOdirPrefix+"Prod?TstDiff.spec");
ProdSpec_Tstd->setComment("spectrum of time stamp difference (microseconds)");
hGroup.add(ProdSpec_Tstd);
}
#endif //CRP_MULTIHIST
......@@ -223,6 +247,24 @@ Int_t CrystalProducerATCA::AlgoSpecificInitialise()
fProdBaseCount = 0;
}
fpProdTstampDiff = NULL;
fProdTstampDiffBuff = NULL;
doWriteTstampDiff = (writeDataMask & 32) != 0;
if(doWriteTstampDiff) {
writeDataMask &= 0xFFFFFFDF; // turn off the bit
std::ostringstream filename;
filename << "event_tstdiff.bdat";
fnProdTstampDiff = fOdirPrefix+filename.str();
cout << "Opening timestamp difference file " << fnProdTstampDiff << endl;
fpProdTstampDiff = fopen(fnProdTstampDiff.c_str(), "wb");
if(!fpProdTstampDiff) {
cout << "Error: could not open " << fnProdTstampDiff << endl;
return 1;
}
fProdTstampDiffBuff = new UInt_t[tStampBuffSize];
}
fProdTstampDiffCount = 0;
File_Finished = false;
bStartCalled = false;
return 0;
......@@ -238,7 +280,7 @@ UInt_t CrystalProducerATCA::ProcessBlock (ADF::FrameBlock &outBlock)
// attach the output buffer to the FrameIO system
fFrameIO.Attach(NULL, &outBlock);
ULong64_t timestamp0 = 0;
ULong64_t timestamp1st = 0;
UInt_t error_code = 0;
UInt_t size_of_output_buffer = UInt_t(outBlock.GetMaxSize());
......@@ -311,8 +353,9 @@ UInt_t CrystalProducerATCA::ProcessBlock (ADF::FrameBlock &outBlock)
Log << error << " During : SetInput()" << dolog;
break;
}
if(nnev == 0) {
timestamp0 = timestamp;
timestamp1st = timestamp;
}
// process the input buffer making some analysis
......@@ -346,7 +389,7 @@ UInt_t CrystalProducerATCA::ProcessBlock (ADF::FrameBlock &outBlock)
used_size_of_output_buffer = UInt_t(outBlock.GetSize());
// save original data to disk in various formats
if(fWriteDataMask > 1) {
if(writeDataMask&0xFFFFFFDE) { // b=1 and b=32 not relevant
error_code = WriteOriginalData(evnumber, timestamp);
if(error_code) {
LOCK_COUT;
......@@ -368,7 +411,7 @@ UInt_t CrystalProducerATCA::ProcessBlock (ADF::FrameBlock &outBlock)
// Check also if enough space in output frame for another 50+2 (for safety) events
// (this second check is fine as long as the event has a fixed size)
if( (nnev%50) == 0 ) {
float tdiff = float((timestamp - timestamp0))/tst1second;
float tdiff = float((timestamp - timestamp1st))/tst1second;
if(tdiff > fTimeStep)
break;
if( (used_size_of_output_buffer + 52*outbufflen) > outputSizeToFill)
......@@ -378,7 +421,7 @@ UInt_t CrystalProducerATCA::ProcessBlock (ADF::FrameBlock &outBlock)
} // while(true) // event loop
// elapsed ACQ time in seconds, assuming 100MS/s
float tdiff = float((timestamp - timestamp0))/tst1second;
float tdiff = float((timestamp - timestamp1st))/tst1second;
unsigned int irate = (tdiff > 0) ? int(nnev/tdiff) : 0;
int rtime = cServer.GetRunTime();
#ifdef CRP_MULTIHIST
......@@ -530,21 +573,34 @@ Int_t CrystalProducerATCA::Process()
ProdSpec_Base->Incr(CrystalInterface::kNbSegments+nn, baseVal);
}
}
if(ProdSpec_Tstd) {
if(tStampOld) {
UInt_t tstdiff = UInt_t((timestamp - tStampOld) & 0xFFFFFFFF);
ProdSpec_Tstd->Incr(tstdiff/100); // assuming 100 Ms/s
}
}
#endif //CRP_MULTIHIST
int rval = 0;
if(fWriteNumTraces > 0) {
int rv = WriteTraces();
if(rv)
return rv;
if( WriteTraces() )
rval |= 1;
}
if(fpProdBases) {
int rv = WriteBaselines();
if(rv)
return rv;
if( WriteBaselines() )
rval |= 2;
}
return 0;
if(doWriteTstampDiff) {
if( WriteTstampDiff() )
rval |= 4;
}
tStampOld = timestamp;
return rval;
}
// UInt_t CrystalProducer::process_block (ADF::FrameBlock &) {double a=0;}
......@@ -642,6 +698,39 @@ int CrystalProducerATCA::WriteBaselines()
return (nwritten != vLen) ? 1 : 0;
}
int CrystalProducerATCA::WriteTstampDiff()
{
if(tStampOld == 0) {
fProdTstampDiffCount = 0;
#if 1
// seconds and fraction of seconds of first timestamp, assuming 100 Ms/s
fProdTstampDiffBuff[fProdTstampDiffCount++] = (int)(timestamp/100000000);
fProdTstampDiffBuff[fProdTstampDiffCount++] = (int)(timestamp-100000000*(timestamp/100000000));
#else
// time stamp of first event, written in little endian
fProdTstampDiffBuff[fProdTstampDiffCount++] = UInt_t(timestamp & 0xFFFFFFFF);
fProdTstampDiffBuff[fProdTstampDiffCount++] = UInt_t(timestamp >> 32);
#endif
return 0;
}
ULong64_t tstdiff = timestamp - tStampOld;
fProdTstampDiffBuff[fProdTstampDiffCount++] = UInt_t(tstdiff & 0xFFFFFFFF);
if(fProdTstampDiffCount == tStampBuffSize) {
if(fwrite(fProdTstampDiffBuff, sizeof(UInt_t), tStampBuffSize, fpProdTstampDiff) != tStampBuffSize) {
cout << "Error writing " << fnProdTstampDiff << " ==> disabled " << endl;
fclose(fpProdTstampDiff);
fpProdTstampDiff = NULL;
doWriteTstampDiff = false;
return 1;
}
fProdTstampDiffCount = 0;
}
return 0;
}
bool CrystalProducerATCA::Decodesetup(std::string setupFile, std::string odirPrefix, bool verbose)
{
int ii, nn;
......@@ -888,11 +977,9 @@ bool CrystalProducerATCA::Decodesetup(std::string setupFile, std::string odirPre
return true;
}
bool CrystalProducerATCA::InitATCA(unsigned int wmask, unsigned int wsplit)
bool CrystalProducerATCA::InitATCA(bool writeOriginal)
{
cout << "\nInitialising File Readers" << endl;
writeDataMask = wmask;
writeDataSplit = wsplit;
bool ok;
int cps = max(1, (int)fValidationRate);
// Performance on my laptop, reading from "raw" files
......@@ -903,8 +990,8 @@ bool CrystalProducerATCA::InitATCA(unsigned int wmask, unsigned int wsplit)
// On-line performance should be checked (in the past we had ~20 kHz)
// Still to be tested is why shooting long traces kills the DAQ when cps < ~100 (?)
for(int nn = 0; nn < DAQ_NFILE; nn++) {
//ok = FA[nn].Reset(fTraceLengthRaw, 6, writeDataMask&1, odir, cps);
ok = FA[nn].Reset(fTraceLengthRaw, MZ[FA[nn].oneMezz].nChan, writeDataMask&1, odir, cps);
//ok = FA[nn].Reset(fTraceLengthRaw, 6, writeOriginal, odir, cps);
ok = FA[nn].Reset(fTraceLengthRaw, MZ[FA[nn].oneMezz].nChan, writeOriginal, odir, cps);
if(!ok)
return false;
}
......
......@@ -48,8 +48,10 @@ private:
unsigned int *Number;
unsigned int *evLost;
unsigned long long tStampErr;
unsigned long long tStampNew;
unsigned long long tStampErr; // used by the local event builder
unsigned long long tStampNew; // used by the local event builder
unsigned long long tStampOld; // to build the time-stamp difference
bool bReaFromFile; // If true read raw data from file else, from what says CrystalProducerATCA.conf
......@@ -64,7 +66,7 @@ private:
public:
bool Decodesetup(std::string setupFile, std::string odirPrefix, bool verbose=false);
bool InitATCA(unsigned int wmask, unsigned int wsplit = 0);
bool InitATCA(bool writeOriginal);
bool StartATCA(int numfiles);
unsigned int NextEventATCA(unsigned int *pTimeout); // this produces events from the AGATA electronics
......@@ -134,10 +136,17 @@ public:
FILE *fpProdBases;
UInt_t fProdBaseCount;
Bool_t doWriteTstampDiff;
std::string fnProdTstampDiff;
FILE *fpProdTstampDiff;
UInt_t *fProdTstampDiffBuff;
UInt_t fProdTstampDiffCount;
#ifdef CRP_MULTIHIST
MultiHist<unsigned int> *ProdSpec_Ampl;
MultiHist<unsigned int> *ProdSpec_Base;
MultiHist<unsigned int> *ProdSpec_Rate;
MultiHist<unsigned int> *ProdSpec_Tstd;
#endif //CRP_MULTIHIST
Float_t enerScale; // energy gain of spectra
......@@ -164,6 +173,7 @@ public:
int WriteTraces();
int WriteBaselines();
int WriteTstampDiff();
int CopyEventTags(unsigned short *vv) {
vv[0] = (unsigned short)((evnumber )&0xFFFF);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment