Commit 395dca73 authored by dino's avatar dino
Browse files

Removed obsolete parts from PreprocessingFilterPSA and PSAFilterGridSearch

git-svn-id: svn://gal-serv.lnl.infn.it/agata/trunk/narval_emulator@1076 170316e4-aea8-4b27-aad4-0380ec0519c9
parent f96d695a
......@@ -1027,10 +1027,6 @@
RelativePath="..\common\cycleServer.h"
>
</File>
<File
RelativePath="..\common\dataPairFile.h"
>
</File>
<File
RelativePath="..\common\misc.cpp"
>
......
......@@ -456,11 +456,19 @@ Int_t PSAFilter::SetOutput(int slot)
CoreE0 = pSlot->CoreE[0];
CoreE1 = pSlot->CoreE[1];
CoreT0 = pSlot->CoreT[0];
CoreT1 = pSlot->CoreT[1];
//#define ADDPSATIME
#ifdef ADDPSATIME
// Add the T0 correction as determined by the PSA. --> The overall Ge-Ge timing becomes ~10% worse, with larger tails.
// If the T0 shift is subtracted the overall ge-ge timing becomes ~2 worse (but very symmetric, meaning added noise).
// Therefore, it is better not to correct. However, one should also question the T0 realignment done in the PSA!
CoreT0 = pSlot->CoreT[0] /*+ pSlot->shiftT0*/;
CoreT1 = pSlot->CoreT[1] /*+ pSlot->shiftT0*/;
// The above seems not to be true if the number of samples used to determine Tzero in PsaFilterGridSearch::FitT0AfterPSA
// is smal: e.g. at nsamps=10 we now get an improvement by 10%. To be tested with a wider dinamycal range.
// Therefore, it is better not to correct. MOreover, one should also question the T0 realignment done in the PSA!
CoreT0 += pSlot->shiftT0;
CoreT1 += pSlot->shiftT0;
#endif
//myAno.Set(crystal_id, 0);
//myAno.fRealSize = sizeof(crystal_id);
......
......@@ -48,24 +48,27 @@ const float lowSegEnergy = 50.f; // segment-energies smaller than this are deco
// The output file debug__0-37-56-F__waves.fsamp is written in pwd and may or may not be rewound at the beginning of every event.
// They produce a large amount of output and are normally used in Debug mode as a graphical inspection tool.
// They are not thread-safe and, due to the fixed-name ouput file, incompatible with multiple crystal analyses.
#if 1 && defined(_DEBUG) // set to 1 to enable writing the intermediate waves while debugging
#if 0 && defined(_DEBUG) // set to 1 to enable writing the intermediate waves while debugging
# define WRITEWORKINGWAVE(p1,p2) WriteWorkingWave(p1, p2)
# define WRITEPARTIALWAVE(p1,p2,p3) WritePartialWave(p1, p2, p3)
#else
# define WRITEWORKINGWAVE(p1,p2)
# define WRITEPARTIALWAVE(p1,p2,p3)
//# define WRITEFITTEDWAVES
# ifdef WRITEFITTEDWAVES
# define WRITEWORKINGWAVE1(p1,p2) WriteWorkingWave(p1, p2)
# endif
#endif
PSAFilterGridSearch::PSAFilterGridSearch()
{
fpPsaTraces = NULL;
fpPsaHits = NULL;
fPsaIndex = 0;
#ifdef WRITE_TSHIFT_CORRECTION
tstmpFileO = NULL;
#endif
gUseAdaptive = true;
gTryTwoHits = false;
gCoarseOnly = false;
......@@ -254,6 +257,56 @@ Int_t PSAFilterGridSearch::AlgoSpecificInitialise()
}
#endif
#if 0 && defined(PSA_MULTIHIST)
{
// Write the complete basis of a segment a <float> spectrum. Normalization is 1000.
// write only NSEGS+CC as they are going to be used (i.e. with differentiated netChargeSeg and CC)
// To get the non-differentiated version uncomment //#define USE_NETCHARGES in FridSearchParameters.h
// To get the whole internal basis replace NCHAN with TCHAN in the definition of numTraces
const int fineStep = fstep;
const int detRadius = 40;
const int detLength = 90;
const int numTraces = NCHAN;
const int theSegment = 3;
int numPts = fBasis.numPts[theSegment];
char chsnum[20]; sprintf(chsnum, "%2.2d", theSegment);
MultiHist<float> *baseXYZ = new MultiHist<float>(numPts, numTraces, NTIME);
baseXYZ->setFileName(fOdirPrefix+"Psa?BaseXYZ.spec_"+std::string(chsnum));
baseXYZ->setComment("the PSA base of segment "+std::string(chsnum));
int errcount = 0;
float bb[TCHAN][NTIME];
float fact = 1000.f/MAXNORM;
int indSpe = 0;
for(int ns = theSegment; ns <=theSegment; ns++) {
for(int np = 0; np < fBasis.numPts[ns]; np++) {
pointPsa *bpt = &fBasis.Pts[ns][np];
memcpy(bb, bpt->amplitude, sizeof(bb));
// copy exactly as is
//for(int ii = 0; ii < NTIME; ii++) {
// float tmp = bb[ns][ii];
// bb[ns][ii] = bb[INDNC][ii];
// bb[INDNC][ii] = tmp;
// tmp = bb[INDCC][ii];
// bb[INDCC][ii] = bb[INDQC][ii];
// bb[INDQC][ii] = tmp;
//}
float *pd = baseXYZ->getData(indSpe++, 0);
if(pd) {
for (int is = 0; is < numTraces; is++) {
for(int it = 0; it < NTIME; it++) {
*pd++ = bb[is][it]*fact;
}
}
}
else
errcount++;
}
}
baseXYZ->write();
delete baseXYZ;
}
#endif
#if 0 && defined(PSA_MULTIHIST)
{
// 3D distribution sum of segment signals (2 mm packed)
......@@ -366,12 +419,6 @@ Int_t PSAFilterGridSearch::AlgoSpecificInitialise()
#endif
} // else { // if(gPsaSegCenter) {
#ifdef WRITE_TSHIFT_CORRECTION
if(doFit_T0) {
tstmpFileO = new dataPairFile<ULong64_t, float>(fOdirPrefix+"Tadjust.fdat", false, true, 1000);
}
#endif
#ifdef PSA_MULTIHIST
if(fUseMultiHist) {
PsaSpecEner = new MultiHist<unsigned int>(40, specLenE);
......@@ -655,10 +702,10 @@ Int_t PSAFilterGridSearch::Process(int slot, int count)
return 0; // nothing more to do
}
// T0 of the event is calculated after the GridSearch by minimizing the Chi2 of the
// Core+NetChargeSegments signal as a function of the time-zero position of the experimental trace.
// T0 of the event is calculated after the GridSearch by minimizing the Chi2 of
// the signal as a function of the time-zero position of the experimental trace.
// If the T0 change is significant (but not out of some limits), GridSearch is repeated...
// The problem with this approach is that all iteration perform a full search,
// The problem with this approach is that every iteration perform a full search,
// ignoring the result of the previous one.
// More logical (and probably much faster) would be that after the first turn,
// a local search (fit?) is performed, starting from the previous positions.
......@@ -684,6 +731,12 @@ Int_t PSAFilterGridSearch::Process(int slot, int count)
PrepareEvent(pSlot, PF, (rpt==0), true); // reset PF, identify the hits and prepare the traces, considering also shifT0
WRITEWORKINGWAVE((float *)PF.tAmplitude, (rpt!=0)); // false --> also rewind the file
#ifdef WRITEFITTEDWAVES
if(PF.numNetCharges != 1 || PF.netChargeSegnum[0] != 0) // only if segment A1
break;
WRITEWORKINGWAVE1((float *)PF.tAmplitude, true); // false --> also rewind the file
#endif
if(!PF.isValid) {
pSlot->crystal_status = 1; // not to be used (anyway there are no hits)
pSlot->numNetSegs = 0;
......@@ -711,7 +764,9 @@ Int_t PSAFilterGridSearch::Process(int slot, int count)
chiDone += abs(rv);
nCalled++;
WRITEWORKINGWAVE((float *)PF.rAmplitude, true);
#ifdef WRITEFITTEDWAVES
WRITEWORKINGWAVE1((float *)PF.rAmplitude, true);
#endif
// 3333333333333333333333333333 move the search-results from PF to pSlot
pSlot->numNetSegs = PF.numNetCharges;
pSlot->isSelected = PF.isSelected;
......@@ -770,13 +825,8 @@ int PSAFilterGridSearch::ProcessTheEvent(pointFull &PF, bool doFull, bool twoHit
PF.AddBaseTrace(bestPoint, scaleFact, PF.samp_first, TIME0);
WRITEWORKINGWAVE((float *)PF.wAmplitude, true);
// select the segments to use for the chi2 loop
MakeLocalMask(PF);
// Prepare sAmplitude from the subset of PF.wAmplitude given by localMask
// MakeSearchWave applies also the delayed differentiation of DIFFLAG samples (if defined)
// With a precalculated metric it must also limit the y-values to avoid overflowing the vector.
PF.MakeSearchWave(1.f, PF.localMask, netChEner);
// prepare sAmplitude from the subset of active segments
MakeSearchWave(PF, 1.f, netChEner);
WRITEPARTIALWAVE((float *)PF.sAmplitude, 1.f/RESCALE, true); // scaled down to get it in natural units
PF.chi2min = float(1.e30);
......@@ -963,10 +1013,8 @@ int PSAFilterGridSearch::ProcessTwoHits(pointFull &PF)
PF.AddBaseTrace(bestPoint, scaleFact, PF.samp_first, TIME0);
WRITEWORKINGWAVE((float *)PF.wAmplitude, true);
// Prepare sAmplitude from the subset of PF.wAmplitude given by localMask
// Apply also the delayed differentiation of DIFFLAG samples (if defined)
MakeLocalMask(PF);
PF.MakeSearchWave(1.f, PF.localMask, netChEner);
// prepare sAmplitude from the subset of active segments
MakeSearchWave(PF, 1.f, netChEner);
WRITEPARTIALWAVE((float *)PF.sAmplitude, 1.f/RESCALE, true);
bool onlyCoarse = gCoarseOnly;
......@@ -2196,6 +2244,33 @@ int PSAFilterGridSearch::SearchAdaptive2(pointFull &PF, int netChSeg, bool bCoar
return chiDone;
}
void PSAFilterGridSearch::MakeSearchWave(pointFull &PF, float fact, float maxVal)
{
// select the active segments
MakeLocalMask(PF);
// calculate sAmplitude
PF.MakeSearchWave(fact, PF.localMask);
#ifndef USE_SSE_VERSION
// if using the mapped-metric vector, limit result to avoid overruns
float yMax = RMETRIC - maxVal * RESCALE - 10.f; // some extra margin
float yMin = -RMETRIC + maxVal * RESCALE + 10.f; // some extra margin
for(int iSegm = 0; iSegm < NCHAN; iSegm++) {
if(PF.localMask[iSegm] != '0') {
float *sA = PF.sAmplitude[iSegm];
for(int kk=0; kk<NTIME; kk++) {
float yy = sA[kk];
if(yy > yMax)
sA[kk] = yMax;
else if(yy < yMin)
sA[kk] = yMin;
}
}
}
#endif
}
void PSAFilterGridSearch::MakeLocalMask(pointFull &PF)
{
// set mask of segments for the search loop
......@@ -2266,9 +2341,8 @@ void PSAFilterGridSearch::PreSearchCoarse(pointFull &PF)
PF.AddBaseTrace(bestPoint, scaleFact, PF.samp_first, TIME0);
WRITEWORKINGWAVE((float *)PF.wAmplitude, true);
// prepare sAmplitude from the subset of wAmplitude given by localMask
MakeLocalMask(PF);
PF.MakeSearchWave(1.f, PF.localMask, netChEner);
// prepare sAmplitude from the subset of active segments
MakeSearchWave(PF, 1.f, netChEner);
WRITEPARTIALWAVE((float *)PF.sAmplitude, scaleFact, true);
PF.chi2min = float(1.e30);
......@@ -2320,11 +2394,6 @@ Int_t PSAFilterGridSearch::AlgoSpecificPostProcess(int slot)
fPsaIndex = (fPsaIndex+1)%16;
}
#ifdef WRITE_TSHIFT_CORRECTION
if(doFit_T0 && tstmpFileO)
tstmpFileO->put(pSlot->timestamp, pSlot->shiftT0);
#endif
// no histogramming requested
if(!pSlot->isSelected)
return 0;
......@@ -2662,19 +2731,28 @@ void PSAFilterGridSearch::MatChi2(float chi, pointPsa* pPsa)
}
#endif // #ifdef MATRCHI2
// use the complete trace
// Use all segments and core to compare the "fitted" trace to the experimental one
// The comparison runs from SAMP0/2 (=-4) to nsams-SAMP0/2 of the fitted trace, while the
// experimental one is shifted for up to +-nsteps
// returns the time shift with respect to SAMP0 in units of samples
Float_t PSAFilterGridSearch::FitT0AfterPSA(pointFull &PF)
{
// calculate chi2 using SAMP0/2 of pretrigger and 20-SAMP0/2 of risetime
const int nsteps = 3; // <= SAMP0/2
const int nsamps = 20;
float x2[2*nsteps+1]; memset(x2, 0, sizeof(x2));
for(int ll = 0; ll <= 2*nsteps; ll++) {
const int nsteps = 4; // <= SAMP0/2
const int nsamps = 10;
const int x2size = 2*nsteps+1;
float x2[x2size];
for(int ll = 0; ll < x2size; ll++)
x2[ll] = -1;
int ssmin = -1;
float x2min = -1.f;
int ll = nsteps; // dl = ll-nsteps
while(ll>=0 && ll<=2*nsteps) {
float chi2 = 0;
for(int iSegm=0; iSegm<NCHAN; iSegm++) {
float * tData = PF.tAmplitude[iSegm] + SAMP0/2 - nsteps + ll;
float * tData = PF.tAmplitude[iSegm] + SAMP0/2 + ll-nsteps;
float * rData = PF.rAmplitude[iSegm] + SAMP0/2;
for(int ii = 0; ii < nsamps; ii++) { // ii = nsteps
float diff = tData[ii] - rData[ii];
......@@ -2682,22 +2760,20 @@ Float_t PSAFilterGridSearch::FitT0AfterPSA(pointFull &PF)
}
} // end loop over the segments
x2[ll] = chi2;
}
// find the minimum
int ssmin = nsteps;
float x2min = x2[nsteps];
for(int ll = 0; ll <= 2*nsteps; ll++) {
if(x2[ll] < x2min) {
if(ll==nsteps || chi2 < x2min) {
ssmin = ll;
x2min = x2[ll];
}
x2min = chi2;
}
if(ssmin==0 || ssmin==2*nsteps)
return float(ssmin-nsteps); // if at the edge
if(x2[ssmin+1] < 0)
ll = ssmin+1; // calculate ssmin+1
else if (x2[ssmin-1] < 0)
ll = ssmin-1; // calculate ssmin-1
else
break; // both sides of ssmin already available
}
// if at the edge
if(ssmin == 0 || ssmin == 2*nsteps)
return float(ssmin-nsteps);
// parabolic interpolation around the minimum
float ym = x2[ssmin-1];
float ys = x2[ssmin ];
......
#ifndef PSAFILTERGRIDSEARCH_H_INCLUDED
#define PSAFILTERGRIDSEARCH_H_INCLUDED
// Define this symbol to write to file a correction to the timestamp of the events
//#define WRITE_TSHIFT_CORRECTION
#ifdef WRITE_TSHIFT_CORRECTION
#include "dataPairFile.h"
#endif
#include "PSAFilter.h"
#include "GridSearchParams.h"
#include "SignalBasis.h"
......@@ -103,10 +97,6 @@ private:
MultiHist<unsigned short> *PsaMatrSeg;
#endif //PSA_MULTIHIST
#ifdef WRITE_TSHIFT_CORRECTION
dataPairFile<ULong64_t, float> *tstmpFileO;
#endif
Int_t gWriteNumTraces;
Bool_t gWritePartialTraces;
......@@ -129,9 +119,10 @@ private:
int SearchFullGrid (pointFull &PF, int netChSeg);
int SearchAdaptive1(pointFull &PF, int netChSeg, bool bCoarseOnly = false, bool bFirstOnly = false); // 1 hit
int SearchAdaptive2(pointFull &PF, int netChSeg, bool bCoarseOnly = false, bool bFirstOnly = false); // 2 hits
void MakeSearchWave (pointFull &PF, float fact, float maxVal);
void MakeLocalMask (pointFull &PF);
float CalcChi2GridPts(int segNum, int pdNum, pointFull &PF);
float CalcChi2Residue(pointFull &PF);
float CalcChi2GridPts(int segNum, int pdNum, pointFull &PF);
bool WriteBaseAverPt(float scale, std::string ext);
bool WriteBasePoint (float scale, pointPsa &pt, FILE *FP);
......
......@@ -333,7 +333,6 @@ public:
}
}
// possible overflow problems with GS_TYPE_INT16
void add(pointPsa &pt) {
x += pt.x;
y += pt.y;
......@@ -388,9 +387,9 @@ public:
}
};
// augmented by members used by the Grid-search algorithm
// describes an event with NumNetCharges fired segments
// a segment can host up to two interaction points
// Augmented by members used by the Grid-search algorithm
// Describes an event with NumNetCharges fired segments
// A segment can host up to two interaction points
class pointExp : public pointPsa
{
public:
......@@ -403,11 +402,11 @@ public:
MEMALIGN_16
float tAmplitude[TCHAN][NTIME]; // the total original experimental data
MEMALIGN_16
float wAmplitude[TCHAN][NTIME]; // the modified experimental data used by the grid search
MEMALIGN_16
float rAmplitude[TCHAN][NTIME]; // the "fitted" trace
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
int resPt1[NSEGS]; // the best 1st solution point for the numNetCharges segments
int resPt2[NSEGS]; // the best 2nd solution point "
......@@ -435,8 +434,8 @@ private:
memset(netChargeEnergy, 0, sizeof(netChargeEnergy));
memset(tAmplitude, 0, sizeof(tAmplitude));
memset(wAmplitude, 0, sizeof(wAmplitude));
memset(rAmplitude, 0, sizeof(rAmplitude));
memset(sAmplitude, 0, sizeof(sAmplitude));
memset(rAmplitude, 0, sizeof(rAmplitude));
memset(resPt1, 0, sizeof(resPt1));
memset(resPt2, 0, sizeof(resPt2));
memset(resFac, 0, sizeof(resFac));
......@@ -463,8 +462,8 @@ public:
memcpy(netChargeEnergy, PF.netChargeEnergy, sizeof(netChargeEnergy));
memcpy(tAmplitude, PF.tAmplitude, sizeof(tAmplitude));
memcpy(wAmplitude, PF.wAmplitude, sizeof(wAmplitude));
memcpy(rAmplitude, PF.rAmplitude, sizeof(rAmplitude));
memcpy(sAmplitude, PF.sAmplitude, sizeof(sAmplitude));
memcpy(rAmplitude, PF.rAmplitude, sizeof(rAmplitude));
memcpy(resPt1, PF.resPt1, sizeof(resPt1));
memcpy(resPt2, PF.resPt2, sizeof(resPt2));
memcpy(resFac, PF.resFac, sizeof(resFac));
......@@ -480,8 +479,7 @@ public:
// Produces sAmplitude from wAmplitude: to get the right dispersion when
// accessing the mapped-metrix value, sAmplitude is further amplified by RESCALE
// Differentiates netChargeSegment and Core, if needed.
// Limits results to avoid overruns in the mapped distance-metric vector (if used)
void MakeSearchWave(float fact, char *mask, float maxVal) {
void MakeSearchWave(float fact, char *mask) {
memset(sAmplitude, 0, sizeof(sAmplitude));
// build sAmplitude from wAmplitude
fact *= RESCALE; // this is to get the final (expt-base) in the right precision
......@@ -490,8 +488,7 @@ public:
float *sA = sAmplitude[iSegm]; // the wave to be composed
float *wA = wAmplitude[iSegm]; // taking the data from this
for(int kk=0; kk<NTIME; kk++) {
float yy = fact*wA[kk];
sA[kk] = yy;
sA[kk] = fact*wA[kk];
}
}
}
......@@ -505,21 +502,6 @@ public:
ptdata = sAmplitude[INDCC];
}
}
// limit result to avoid overruns in the distance mapped-metric vector
float yMax = RMETRIC - maxVal * RESCALE - 10.f; // some extra margin
float yMin = -RMETRIC + maxVal * RESCALE + 10.f; // some extra margin
for(int iSegm = 0; iSegm < NCHAN; iSegm++) {
if(mask[iSegm] != '0') {
float *sA = sAmplitude[iSegm];
for(int kk=0; kk<NTIME; kk++) {
float yy = sA[kk];
if(yy > yMax)
sA[kk] = yMax;
else if(yy < yMin)
sA[kk] = yMin;
}
}
}
}
// Modify wAmplitude (float) adding the base point passed in pPsa
......@@ -577,7 +559,7 @@ public:
}
}
// search fraction of core amplitude in the total trace
// Search fraction of core amplitude in the total trace (no more used)
void SearchLimits(float fract, float thresh, int &first, int &last) {
first = addr_first;
last = addr_last;
......
......@@ -9,6 +9,8 @@
#include "AgataKeyFactory.h"
#include "AgataFrameFactory.h"
#include "DFAgent.h"
#include <iostream>
#include <iomanip>
#include <fstream>
......@@ -117,6 +119,14 @@ void PostPSAFilter::process_initialise (UInt_t *error_code)
UInt_t rerr = 0;
cout << endl;
// const std::list<std::pair <FactoryItem,FactoryItem> > & kf = GetConfAgent()->GetDFAgent()->GetListOfKnownFrames();
//std::list< std::pair<FactoryItem,FactoryItem> >::const_iterator lit;
// int ii = 0;
// cout << " **** List of known frames **** " << endl;
// for(lit = kf.begin(); lit != kf.end(); lit++, ii++) {
// cout << setw(3) << ii << " " << lit->first << " " << lit->second << endl;
// }
fPSAFrameIn = fTrigger.Add("Agata", "data:psa"); // discard input data
if( fPSAFrameIn ) {
// link named items with local variables.
......
......@@ -10,11 +10,9 @@
using namespace std;
using namespace ADF;
// Specific for the tests performed by Francesco (in DATE??) injecting a triangular pulse directly to the input of the digitizers
// in order determine the time-resolution limits due to clock jiitter and power noise
// As the these parts are used rarely, they have been removed from their positions and put at the beginning of calcTTPulser().
// In case of use, they should be put back manually in the proper places as explained there.
//#define PULSER_ON_CC_A1_A2
// The parts related to the timing tests done by Francesco using triangular
// pulses, which were enabled by #define PULSER_ON_CC_A1_A2, have been removed
// In case of need, look to revisions < 1064
const int specLenE = 16*1024; // size of energy spectra
const int specOffE = 0; // 2*1024; // offset to see the negative amplitudes in the segments
......@@ -32,7 +30,6 @@ const float xFactor = 500.f; // scaling factor for the differential cro
// The parabolic fit of the risetime has been removed because the extra degree of freedom leads to strange results (e.g. no zero-crossing)
//PULSER_ON_CC_A1_A2((0)) (reminder to put back the proper piece of code when analyzing data taken with the external pulser; see the other related comments)
const int trigChansCC = 5; // normally 4
const int trigChansSG = 5; // normally 4
const float trigFraction = .05f; // start fitting strightline at this fraction of max amplitude (but not lower than trigLevel1)
......@@ -44,7 +41,7 @@ const float tScale = tStep; // 1ns/ch
const int tGain = 10; // 1; // to increase the scale and length of ...TT1 and ...TT2 spectra in a (more or less) consistent way
const int speTTlen = int(1000*tScale);
#if 1 && defined(_DEBUG) // set to 1 to enable writing the intermediate waves while debugging
#if 0 && defined(_DEBUG) // set to 1 to enable writing the intermediate waves while debugging
# define WRITEWORKINGWAVE1(p1,p2) WriteWorkingWave(p1, p2)
#ifdef TIMING_CFD
# define WRITEWORKINGWAVE2(p1,p2) WriteWorkingWave(p1, p2)
......@@ -79,12 +76,6 @@ PreprocessingFilterPSA::PreprocessingFilterPSA() :
firstEventPP = true;
#ifdef READ_TSHIFT_CORRECTION
tstmpFileI = NULL;
fTimestampOld = 0;
fValueOld = 0;
#endif
#ifdef TIMING_CFD
mwd = NULL;
#endif
......@@ -202,10 +193,6 @@ Int_t PreprocessingFilterPSA::AlgoSpecificInitialise()
ResetTraceLength();
#ifdef READ_TSHIFT_CORRECTION
tstmpFileI = new dataPairFile<ULong64_t, float>(GetConfPath()+"Tadjust.fdat", false, false, 1000);
#endif
// these are initialized to the maximum length
if(fCC ) delete [] fCC; fCC = new float [defTraceLengthRaw]; memset(fCC, 0, sizeof(float)*defTraceLengthRaw);
if(fSG ) delete [] fSG; fSG = new float [defTraceLengthRaw]; memset(fSG, 0, sizeof(float)*defTraceLengthRaw);
......@@ -725,13 +712,14 @@ bool PreprocessingFilterPSA::ProcessEvent(int &segMult, float &eSumSG1, float
eSumSG2 = eSumSG1 = sumSegs; // set to this for the case of no crosstalk correction
#ifdef PPF_MULTIHIST
// THIS HAS NOT BEEN DONE BY THIS PROGRAM SINCE LONG TIME --> CHECK if still working or, better, USE sortEnergy
// THIS HAS NOT BEEN DONE BY THIS PROGRAM SINCE LONG TIME --> CHECK if still working or, better, USE SortEnergy
// xTalk only for segment multiplicity = 1
if(PreMatrXT && nSegFold == 1)
calcXTmatrix(SegE);
#endif
//// cross-talk correction for the segment energies (cross talk of traces applied to the signal basis)
//// cross-talk correction for the segment energies
// (cross talk of traces is applied to the signal basis in PSAFilterGridSearch)
if(CC.doecalF2) {
segMult =
xTalkCorrAll(SegE, sumSegs); // the number of hit segments can change due to the increase of energy produced by the xTalk correction
......@@ -810,11 +798,10 @@ bool PreprocessingFilterPSA::ProcessEvent(int &segMult, float &eSumSG1, float
//// select which of the calculated waves to use for triggering
float *fTU = fTrigUseOnlyCC ? fTC : fTT; // core alone or core + net-charge segments
float tRefCC = FindTriggerTime(fTU, trigFraction, trigChansCC); //PULSER_ON_CC_A1_A2((1))
float tRefCC = FindTriggerTime(fTU, trigFraction, trigChansCC);
WRITEWORKINGWAVE1(fTU, true);
WRITEWORKINGWAVE2(mwd->MWDptrTFA(), true); // timing filter wave from the trigger
WRITEWORKINGWAVE2(mwd->MWDptrCFD(), true); // cfd wave in the trigger
//CheckTiming(fTC); // use only the core (only to understand the shape of the time spectra)
//// save a copy of the TFA and CFD shaping for WriteTraces
#ifdef TIMING_CFD
......@@ -834,18 +821,15 @@ bool PreprocessingFilterPSA::ProcessEvent(int &segMult, float &eSumSG1, float
//// what if timing too bad ??
bBadCFD = (tRefCC < 1.f);
#ifdef TIME_AVERAGE
if( bBadCFD )
tRefCC = tAverage.Get(eCore); // value taken from the stored averages
else
tAverage.Set(eCore, tRefCC); // value used to improve averages
#else
if( bBadCFD )
return false; // discard the event
#endif
//// put both trigger times to the same value
CoreT[0] = CoreT[1] = tRefCC /*+ CC.pCC[iTR].tmove/tStep*/;
// Due to the fact that the GTS tree alignment is done only up to the Preprocessing electronics an
// (and not down to the Digitizer) the correction CC.pCC[iTR].tmove/tStep does not adjust the
// Tgamma-gamma of all detector pairs to be in the same position. Therefore it does not make sense to apply it.
// In fact, in PostPSAFilter.conf we can give the (empyrically determined) proper value with the keyword ShiftCC
CoreT[0] = CoreT[1] = tRefCC /*+ CC.pCC[iTR].tmove/tStep*/; // not to be used
#if 0
//// select only events in a given time range
......@@ -867,7 +851,7 @@ bool PreprocessingFilterPSA::ProcessEvent(int &segMult, float &eSumSG1, float
}
if(PreSpecTT1) {
// absolute and relative time spectra (done before shifting the waves)
calcTT(tRefCC, PreSpecTT1, PreMatrTT1, PreMatrEsTs); //PULSER_ON_CC_A1_A2((2))
calcTT(tRefCC, PreSpecTT1, PreMatrTT1, PreMatrEsTs);
}
#endif // PPF_MULTIHIST
......@@ -879,10 +863,7 @@ bool PreprocessingFilterPSA::ProcessEvent(int &segMult, float &eSumSG1, float
// fHandShift is an ad-hoc common shift to have the traces well positioned in the PSA.
float fHandShift = CC.pCC[iTR].tmove/tStep; // is interpreted as global shift
float fshiftCC = (defTriggerSample+defTriggerSamplePlus) - tRefCC + fHandShift;
#ifdef TSHIFT_CORRETCTION
float extraShift = getTstampFileValue(timestamp);