Commit c14cdb6c authored by dino's avatar dino
Browse files

Calculation of the energy partition between the hits in PSAFilterGridSearch...

Calculation of the energy partition between the hits in PSAFilterGridSearch when using AdaptiveTwoHits is
now done analytically, no more with a loop on possible values.
Some adjustments in TrackingFilter::SetOutput so that the adf tracked frame structure contains position and energy in the gamma-related part.

git-svn-id: svn://gal-serv.lnl.infn.it/agata/trunk/narval_emulator@1077 170316e4-aea8-4b27-aad4-0380ec0519c9
parent 395dca73
...@@ -101,7 +101,7 @@ DISPATCHER EventBuilder pseudo actor to connect the output of the ch ...@@ -101,7 +101,7 @@ DISPATCHER EventBuilder pseudo actor to connect the output of the ch
#endif #endif
// Replacement of Xavier's variable to ask producers to return from process_block even // Replacement of Xavier's variable to ask producers to return from process_block even
// if the buffer is not yet full. This is just to avoid complains from the compiler, not // if the buffer is not yet full. This is just to avoid complaints from the compiler, not
// an implementation of the time-out mechanism (which is not very meaningful in off-line). // an implementation of the time-out mechanism (which is not very meaningful in off-line).
unsigned int library_timeout = 0; unsigned int library_timeout = 0;
......
...@@ -459,13 +459,14 @@ Int_t PSAFilter::SetOutput(int slot) ...@@ -459,13 +459,14 @@ Int_t PSAFilter::SetOutput(int slot)
CoreT0 = pSlot->CoreT[0]; CoreT0 = pSlot->CoreT[0];
CoreT1 = pSlot->CoreT[1]; CoreT1 = pSlot->CoreT[1];
//#define ADDPSATIME #define ADDPSATIME
#ifdef ADDPSATIME #ifdef ADDPSATIME
// Add the T0 correction as determined by the PSA. --> The overall Ge-Ge timing becomes ~10% worse, with larger tails. // Add the T0 correction as determined by the PSA.
// If the T0 shift is subtracted the overall ge-ge timing becomes ~2 worse (but very symmetric, meaning added noise). // Using a large number of samples (nsamples>20) in PsaFilterGridSearch::FitT0AfterPSA to determine Tzero,
// The above seems not to be true if the number of samples used to determine Tzero in PsaFilterGridSearch::FitT0AfterPSA // Tgamma-gamma becomes ~10% worse than using only the timing done in PreprocessingFilterPSA.
// is smal: e.g. at nsamps=10 we now get an improvement by 10%. To be tested with a wider dinamycal range. // With (nsamples=10) Tgamma-gamma improves by ~10% but the peaks start getting tails.
// Therefore, it is better not to correct. MOreover, one should also question the T0 realignment done in the PSA! // A reasonable compromise seems to be (nsamples=15), but the Tgamma-gamma improvement is rather modest.
// This matter is not completely clarified and one can decide to ignore the correction by commenting the #define ADDPSATIME.
CoreT0 += pSlot->shiftT0; CoreT0 += pSlot->shiftT0;
CoreT1 += pSlot->shiftT0; CoreT1 += pSlot->shiftT0;
#endif #endif
......
This diff is collapsed.
...@@ -314,15 +314,24 @@ INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal, const ...@@ -314,15 +314,24 @@ INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal, const
// The multiplication * baseScale costs ~ 5% in terms of speed. It could be avoided by pre-scaling the experimental trace // The multiplication * baseScale costs ~ 5% in terms of speed. It could be avoided by pre-scaling the experimental trace
// in such a way that bScale == 1. In this case the mapped-metrics vector is applied with a varying scale and loses its // in such a way that bScale == 1. In this case the mapped-metrics vector is applied with a varying scale and loses its
// statistical meaning (if it ever had one, like e.g. with the biweight). // statistical meaning (if it ever had one, like e.g. with the biweight).
//
// avoid mapped metric if STANDARD_METRIC == STANDARD_METRIC_SQUARE
// loop with 0 hits // loop with 0 hits
INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal) INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal)
{ {
#if STANDARD_METRIC != STANDARD_METRIC_SQUARE
const float *metric = mappedMetric + RMETRIC; const float *metric = mappedMetric + RMETRIC;
#endif
float chi2 = 0; float chi2 = 0;
for(int nn = 0; nn < LOOP_SAMP; nn++) { for(int nn = 0; nn < LOOP_SAMP; nn++) {
#if STANDARD_METRIC == STANDARD_METRIC_SQUARE
float fdiff = pReal[nn];
chi2 += fdiff*fdiff;
#else
int idiff = int(pReal[nn]); int idiff = int(pReal[nn]);
chi2 += metric[idiff]; chi2 += metric[idiff];
#endif
} }
return chi2; return chi2;
} }
...@@ -330,28 +339,34 @@ INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal) ...@@ -330,28 +339,34 @@ INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal)
// loop with 1 hit // loop with 1 hit
INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal, const float *pBase, float bScale) INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal, const float *pBase, float bScale)
{ {
#if STANDARD_METRIC != STANDARD_METRIC_SQUARE
const float *metric = mappedMetric + RMETRIC; const float *metric = mappedMetric + RMETRIC;
#endif
float chi2 = 0; float chi2 = 0;
for(int nn = 0; nn < LOOP_SAMP; nn++) { for(int nn = 0; nn < LOOP_SAMP; nn++) {
float fdiff = pReal[nn] - bScale * pBase[nn]; float fdiff = pReal[nn] - bScale * pBase[nn];
#if STANDARD_METRIC == STANDARD_METRIC_SQUARE
chi2 += fdiff*fdiff;
#else
int idiff = int(fdiff); int idiff = int(fdiff);
chi2 += metric[idiff];
//////chi2 += fabs(diff); // direct calculation of pow(|d|, 1 )
//////chi2 += diff*diff; // direct calculation of pow( d , 2 )
//////chi2 += sqrt(fabs(diff)); // direct calculation of pow(|d|, 1/2)
//////chi2 += sqrt(sqrt(fabs(diff))); // direct calculation of pow(|d|, 1/4)
//////chi2 += pow(fabs(diff), float(PMETRIC)); // direct use of the pow function --> very slow
//////const float wwww = -1.f/(2*30.f*30.f);
//////chi2 += 1.f - exp(diff*diff*wwww); // direct use of the 1-exp(-d^2) function --> very slow
#ifdef SPECMETRIC #ifdef SPECMETRIC
// This block is to check that the size of "metrics", is big enough to address all // This block is to check if the size of "metrics" is big enough to address all
// possible values of "diff". If enabled, it slows very much down the execution. // possible values of "idiff". If enabled, it slows very much down the execution.
// As MultiHist is not thread safe, be sure that you are NOT USING THREADS. // As MultiHist is not thread safe, be sure that you are NOT USING THREADS.
if(specMetrics) specMetrics->incr(idiff+RMETRIC); if(specMetrics) specMetrics->incr(idiff+RMETRIC);
if(idiff<=-RMETRIC+2 || idiff> RMETRIC-2) { if(idiff<=-RMETRIC+2 || idiff> RMETRIC-2) {
int nerrr = 1; // to catch the outliers with the debugger int nerrr = 1; // to catch the outliers with the debugger
} }
#endif #endif // SPECMETRIC
chi2 += metric[idiff]; #endif // STANDARD_METRIC == STANDARD_METRIC_SQUARE
//chi2 += pow(fabs(diff), float(PMETRIC)); // direct use of the pow function --> very slow
//chi2 += diff*diff; // direct calculation of pow( d , 2 )
//chi2 += fabs(diff); // direct calculation of pow(|d|, 1 )
//chi2 += sqrt(fabs(diff)); // direct calculation of pow(|d|, 1/2)
//chi2 += sqrt(sqrt(fabs(diff))); // direct calculation of pow(|d|, 1/4)
//const float wwww = -1.f/(2*30.f*30.f);
//chi2 += 1.f - exp(diff*diff*wwww); // direct use of the 1-exp(-d^2) function --> very slow
} }
return chi2; return chi2;
} }
...@@ -359,26 +374,32 @@ INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal, const ...@@ -359,26 +374,32 @@ INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal, const
// loop with 2 hits // loop with 2 hits
INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal, const float *pBase1, float bScale1, const float *pBase2, float bScale2) INLINE_ALWAYS float PSAFilterGridSearch::Chi2InnerLoop(const float *pReal, const float *pBase1, float bScale1, const float *pBase2, float bScale2)
{ {
#if STANDARD_METRIC != STANDARD_METRIC_SQUARE
const float *metric = mappedMetric + RMETRIC; const float *metric = mappedMetric + RMETRIC;
#endif
float chi2 = 0; float chi2 = 0;
for(int nn = 0; nn < LOOP_SAMP; nn++) { for(int nn = 0; nn < LOOP_SAMP; nn++) {
float fdiff = pReal[nn] - (bScale1*pBase1[nn] + bScale2*pBase2[nn]); float fdiff = pReal[nn] - (bScale1*pBase1[nn] + bScale2*pBase2[nn]);
int idiff = int(fdiff); #if STANDARD_METRIC == STANDARD_METRIC_SQUARE
chi2 += fdiff*fdiff;
#else
int xdiff = int(fdiff);
chi2 += metric[idiff]; chi2 += metric[idiff];
#endif
} }
return chi2; return chi2;
} }
#endif // #else // #ifdef USE_SSE_VERSION ////// Performance obtained qite some time ago with various types of chi2
//////chi2 += metric[int(diff)]; // 160 evts/s map0
//////chi2 += metric[int(fabs(diff)); // 115 evts/s map1
//////chi2 += metric[abs(int(diff)); // 145 evts/s map2
//////chi2 += abs(diff); // 145 evts/s abs
//////chi2 += diff*diff; // 290 evts/s sqr
//////chi2 += sqrt(fabs(diff)); // 60 evts/s 1sqrt
//////chi2 += sqrt(sqrt(fabs(diff))); // 30 evts/s 2sqrt
//////chi2 += pow(fabs(diff), float(gDistMetric)); // 4 evts/s pow
// Performance obtained some time ago with various types of chi2 #endif // #else // #ifdef USE_SSE_VERSION
//chi2 += metric[int(diff)]; // 160 evts/s map0
//chi2 += metric[int(fabs(diff)); // 115 evts/s map1
//chi2 += metric[abs(int(diff)); // 145 evts/s map2
//chi2 += pow(fabs(diff), float(gDistMetric)); // 4 evts/s pow
//chi2 += abs(diff); // 145 evts/s abs
//chi2 += diff*diff; // 290 evts/s sqr
//chi2 += sqrt(fabs(diff)); // 60 evts/s 1sqrt
//chi2 += sqrt(sqrt(fabs(diff))); // 30 evts/s 2sqrt
#endif // PSAFILTERGRIDSEARCH_H_INCLUDED #endif // PSAFILTERGRIDSEARCH_H_INCLUDED
...@@ -118,7 +118,8 @@ public: ...@@ -118,7 +118,8 @@ public:
sumDiffNetSeg = 0; sumDiffNetSeg = 0;
for(int ns = 0; ns < NSEGS; ns++) { for(int ns = 0; ns < NSEGS; ns++) {
float sum = 0; float sum = 0;
for(int ii = 0; ii < NTIME; ii++) //for(int ii = 0; ii < NTIME; ii++)
for(int ii = 0; ii < LOOP_SAMP; ii++) // to reflect real use and minimize contribution of proportional cross-talk
sum += amplitude[ns][ii]; sum += amplitude[ns][ii];
if(ns==netChargeSegment) if(ns==netChargeSegment)
sumDiffNetSeg = sum; sumDiffNetSeg = sum;
......
...@@ -1189,18 +1189,24 @@ Int_t TrackingFilter::SetOutput() ...@@ -1189,18 +1189,24 @@ Int_t TrackingFilter::SetOutput()
for(Int_t ii = 0; ii < number_of_gammas; ii++, pG++ ) { for(Int_t ii = 0; ii < number_of_gammas; ii++, pG++ ) {
TrackedHit *ahit = trackdata->NewGamma(); TrackedHit *ahit = trackdata->NewGamma();
ahit->SetStatus(0); ahit->SetStatus(0);
ahit->SetE(pG->E); // passed over in units of keV ahit->SetE(pG->E); // energy, passed over in units of keV
//ahit->SetXYZ(pG->X1, pG->Y1, pG->Z1); // 3D position of the tracked gamma is the first hit (must be given explicitly in version(65000,n)) ahit->SetXYZ(pG->X1, pG->Y1, pG->Z1); // 3D position of the tracked gamma is the first hit
exyzHit *pP = pEXYZ + pG->I1; // original PSA hit of the the first interaction point of the tracked gamma exyzHit *pP = pEXYZ + pG->I1; // original PSA hit of the the first interaction point of the tracked gamma
for(Int_t nh = 0; nh < min(2,pG->nH); nh++) { for(Int_t nh = 0; nh < pG->nH; nh++) { // Decision on how many hits to write taken later in if(nh==0) and if(pG-type!=2)
Hit *pH = ahit->NewHit(); // Hit *pH = ahit->NewHit(); // BEST OF ALL WOULD BE TO WRITE ALL HITS IN THE PROPER SEQUENCE!! (OR TO USE A FLAG)
pH->SetXYZ(pP->X, pP->Y, pP->Z); // info taken from the original PSA hit pH->SetXYZ(pP->X, pP->Y, pP->Z); // info taken from the original PSA hit
pH->SetE (pP->E); pH->SetE (pP->E);
pH->SetT (pP->T); // info taken from the original PSA hit pH->SetT (pP->T); // info taken from the original PSA hit
pH->SetID(pP->Seg,0); pH->SetID(pP->Seg,0);
pH->SetID(pP->Det,1); pH->SetID(pP->Det,1);
if(nh==0 && pG->type==2) if(nh==0) {
ahit->SetT(pP->T); // time of the tracked gamma taken from its first hit
//ahit->SetID(pP->Seg, 0); // there is no such field in TrackedHit
//ahit->SetID(pP->Ind, 1); // ""
if(pG->type!=2) // Photoelectric and Pair Production write only on hit. When reading back the
break; // adf file they differ in Egamma_photo = Ehit vs Egamma_PP ~ Ehit + 1022
pP = pEXYZ + pG->I2; pP = pEXYZ + pG->I2;
}
} }
} }
......
...@@ -769,13 +769,14 @@ bool CrystalProducerATCA::Decodesetup(std::string setupFile, std::string odirPre ...@@ -769,13 +769,14 @@ bool CrystalProducerATCA::Decodesetup(std::string setupFile, std::string odirPre
cout << "value(s) out of range in { " << line << " }" << endl; cout << "value(s) out of range in { " << line << " }" << endl;
return false; return false;
} }
MZ[mezznum].myID = mezznum; MZ[mezznum].myID = mezznum;
MZ[mezznum].nFile = filenum; MZ[mezznum].nFile = filenum;
MZ[mezznum].nSlot = slotnum; MZ[mezznum].nSlot = slotnum;
MZ[mezznum].nChan = numchan; MZ[mezznum].nChan = numchan;
MZ[mezznum].zMask = zmask; MZ[mezznum].zMask = zmask;
MZ[mezznum].fATCA = FA + filenum; MZ[mezznum].fATCA = FA + filenum;
FA[filenum].Enable(slotnum); FA[filenum].Enable(slotnum);
FA[filenum].oneMezz = mezznum;
cout << line << endl; cout << line << endl;
} }
...@@ -881,7 +882,8 @@ bool CrystalProducerATCA::InitATCA(unsigned int wmask, unsigned int wsplit) ...@@ -881,7 +882,8 @@ bool CrystalProducerATCA::InitATCA(unsigned int wmask, unsigned int wsplit)
bool ok; bool ok;
int cps = max(1, (int)fValidationRate); int cps = max(1, (int)fValidationRate);
for(int nn = 0; nn < DAQ_NFILE; nn++) { for(int nn = 0; nn < DAQ_NFILE; nn++) {
ok = FA[nn].Reset(fTraceLengthRaw, 6, writeDataMask&1, odir, cps); //ok = FA[nn].Reset(fTraceLengthRaw, 6, writeDataMask&1, odir, cps);
ok = FA[nn].Reset(fTraceLengthRaw, MZ[FA[nn].oneMezz].nChan, writeDataMask&1, odir, cps);
if(!ok) if(!ok)
return false; return false;
} }
......
...@@ -35,7 +35,7 @@ class fileATCA ...@@ -35,7 +35,7 @@ class fileATCA
public: public:
fileATCA() : fileID(-1), crystID(-1), ifd(-1), thePR(NULL), readMezz(NULL), fileATCA() : fileID(-1), crystID(-1), ifd(-1), thePR(NULL), readMezz(NULL),
fromDAQ(false), bValid(false), giveUp(false), bTraces(true), fromDAQ(false), bValid(false), giveUp(false), bTraces(true),
numMezz(0), numChan(0), lenTrace(0), lenMezzData(0), lenMezzTotal(0), numMezz(0), oneMezz(0), numChan(0), lenTrace(0), lenMezzData(0), lenMezzTotal(0),
nfiles(0), fnstep(1), nfiles(0), fnstep(1),
bIncrLast(false), bWrite(false), iFILE(NULL), rFILE(NULL), oldmezz(0xFFFFFFFF), bIncrLast(false), bWrite(false), iFILE(NULL), rFILE(NULL), oldmezz(0xFFFFFFFF),
rawDataBuffer(NULL), uBuff(NULL), uMezz(0), nMezz(0), rawDataBuffer(NULL), uBuff(NULL), uMezz(0), nMezz(0),
...@@ -78,7 +78,8 @@ public: ...@@ -78,7 +78,8 @@ public:
mezzanine *readMezz; mezzanine *readMezz;
unsigned int numMezz; // number of mezzanines written in this file unsigned int numMezz; // number of mezzanines written in this file
unsigned int numChan; // number of channels in this mezzanine (normally 6) unsigned int oneMezz; // index of one of the all-equal mezzanines associated to this file
unsigned int numChan; // number of channels in the mezzanines of this file (normally 6)
unsigned int lenTrace; // unsigned int lenTrace; //
unsigned int lenMezzData; // expected number of samples unsigned int lenMezzData; // expected number of samples
unsigned int lenMezzTotal; // total length of one mezzanine unsigned int lenMezzTotal; // total length of one mezzanine
......
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