1) Bug removed from the simulation of optical photons with the option "APDcellsEffectRequested" -- namely, when any simulated photon hit a given APD cell, the cell became "blind" to any other photon, irrespective of the arrival time of the next photon. However, we need that if the "second" photon (simulated at later phase) enters the APD cell before the "first" one, that the time of photon arrival changes to the earlierst photon. 2) A new keyword "sampleID ..." (defining which volume is the sample volume) was added to the musrSimAna. The manual was updated accordingly.
335 lines
18 KiB
C++
335 lines
18 KiB
C++
//#include <iostream>
|
|
#include "musrCounter.hh"
|
|
#include "TCanvas.h"
|
|
|
|
typedef std::map<int,int> debugEventMapType;
|
|
debugEventMapType debugEventMap;
|
|
Bool_t bool_debugingRequired;
|
|
|
|
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
|
|
|
musrCounter::musrCounter(int CHANNEL_NR, char CHANNEL_NAME[200], char CHANNEL_TYPE, float E_THRESH, int TIME_SHIFT) {
|
|
// pointerToAnalysis=this;
|
|
counterNr = CHANNEL_NR;
|
|
strcpy(counterName,CHANNEL_NAME);
|
|
counterType = CHANNEL_TYPE;
|
|
couterEThreshold = E_THRESH;
|
|
counterTimeShift = (Long64_t) TIME_SHIFT;
|
|
std::cout<<"musrCounter::musrCounter: Creating counter "<<counterNr<<" "<<counterName<<" "<<counterType<<" "<<couterEThreshold<<" "<<counterTimeShift<<std::endl;
|
|
strcpy(TDC_histoName,"Unset");
|
|
TDC_t0=0;
|
|
TDC_t1=0;
|
|
TDC_t2=0;
|
|
TDC_histoNrAdd=0;
|
|
antiCoincidenceTimeWindowMin=0;
|
|
antiCoincidenceTimeWindowMax=0;
|
|
coincidenceTimeWindowMin_M=0;
|
|
coincidenceTimeWindowMax_M=0;
|
|
coincidenceTimeWindowMin_P=0;
|
|
coincidenceTimeWindowMax_P=0;
|
|
maxCoincidenceTimeWindow=0;
|
|
strcpy(TDC_histoNameAdd,"Unset");
|
|
doubleHitN=0;
|
|
numberOfMuonCandidates=0;
|
|
numberOfMuonCandidatesAfterVK=0;
|
|
numberOfMuonCandidatesAfterVKandDoubleHitRemoval=0;
|
|
}
|
|
|
|
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
|
|
|
musrCounter::~musrCounter() {}
|
|
|
|
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
|
|
|
void musrCounter::SetTDChistogram(char hName[200],int t0,int t1,int t2,int hNr,char hNameAdd[200]) {
|
|
strcpy(TDC_histoName,hName);
|
|
TDC_t0=t0;
|
|
TDC_t1=t1;
|
|
TDC_t2=t2;
|
|
TDC_histoNrAdd=hNr;
|
|
strcpy(TDC_histoNameAdd,hNameAdd);
|
|
std::cout<<"TDC_histogram: "<<TDC_histoName<<" "<<TDC_t0<<" "<<TDC_t1<<" "<<TDC_t2<<" "<<TDC_histoNrAdd<<" "<<TDC_histoNameAdd<<std::endl;
|
|
histTDC = new TH1D(TDC_histoName,TDC_histoName,t2,0.,float(t2));
|
|
}
|
|
//================================================================
|
|
void musrCounter::FillTDChistogram(Double_t variable, Double_t vaha) {
|
|
histTDC->Fill(variable,vaha);
|
|
}
|
|
|
|
//================================================================
|
|
void musrCounter::DrawTDChistogram() {
|
|
char canvasName[501];
|
|
sprintf(canvasName,"c%s",TDC_histoName);
|
|
TCanvas* cTmp = new TCanvas(canvasName,canvasName);
|
|
histTDC->Draw();
|
|
}
|
|
|
|
//================================================================
|
|
void musrCounter::FillHitInCounter(Double_t edep, Long64_t timeBin, Long64_t timeBin2, Int_t kEntry, Int_t eveID, Int_t iDet, Int_t detectorID){
|
|
//cDEL std::cout<<"FillHitInCounter: timeBin="<<timeBin<<" timeBin2="<<timeBin2<<" counterTimeShift="<< counterTimeShift<<std::endl;
|
|
//cDEL std::cout<<" FillHitInCounter I: timeBin-counterTimeShift="<<timeBin-counterTimeShift<<" timeBin2-counterTimeShift="<<timeBin2-counterTimeShift<<std::endl;
|
|
// std::cout<<"musrCounter::FillHitInCounter:"<<counterNr<<std::endl;
|
|
if (edep>=couterEThreshold) {
|
|
|
|
hitInfo* hInfo = new hitInfo(kEntry,eveID,iDet,detectorID,edep,timeBin2-counterTimeShift);
|
|
//cDEL std::cout<<detectorID<<" FillHitInCounter II: timeBin-counterTimeShift="<<timeBin-counterTimeShift<<" timeBin2-counterTimeShift="<<timeBin2-counterTimeShift<<std::endl;
|
|
hitMap.insert( std::pair<Long64_t,hitInfo*>(timeBin-counterTimeShift,hInfo) );
|
|
}
|
|
}
|
|
|
|
//================================================================
|
|
void musrCounter::RemoveHitsInCounter(Long64_t timeBinLimit) {
|
|
// Remove the obsolete hits (i.e. hits that happaned well before t0) from the Counter class
|
|
if (hitMap.empty()) return;
|
|
// myPrintThisCounter();
|
|
// if (counterNr==1) {std::cout<<"ooooo1 timeBinLimit="<<timeBinLimit<<std::endl; myPrintThisCounter();}
|
|
for (hitMap_TYPE::iterator it = hitMap.begin(); it != hitMap.end(); ++it) {
|
|
// std::cout<<" musrCounter::RemoveHitsInCounter: counterNr="<<counterNr<<" timeBinLimit="<<timeBinLimit<<" maxCoincidenceTimeWindow="<<maxCoincidenceTimeWindow<<" counterTimeShift="<<counterTimeShift<<std::endl;
|
|
if ((it->first)>(timeBinLimit+maxCoincidenceTimeWindow-counterTimeShift)) return; //note that maxCoincidenceTimeWindow is usually negative number
|
|
else {
|
|
// std::cout<<" Deleting hit from counter "<<counterNr<<", time bin = "<<(it->first)<<std::endl;
|
|
delete (it->second);
|
|
hitMap.erase(it);
|
|
}
|
|
}
|
|
// if (counterNr==1) {std::cout<<"ooooo2"<<std::endl; myPrintThisCounter();}
|
|
}
|
|
|
|
//================================================================
|
|
void musrCounter::RewindHitsInCounter(Long64_t timeBinsToRewind) {
|
|
// Reset time in hits from the Counter class
|
|
if (hitMap.empty()) return;
|
|
|
|
hitMap_TYPE hitMap_TMP;
|
|
for (hitMap_TYPE::iterator it = hitMap.begin(); it != hitMap.end(); ++it) {
|
|
// std::cout<<"musrCounter::RewindHitsInCounter: "<<std::endl;
|
|
Long64_t tempBinT = it->first;
|
|
// int tempEvnr= it->second;
|
|
// hitMap_TMP.insert( std::pair<Long64_t,int>(tempBinT-timeBinsToRewind,tempEvnr) );
|
|
hitInfo* tempEvnr= it->second;
|
|
tempEvnr->RewindTimeBin2(timeBinsToRewind);
|
|
hitMap_TMP.insert( std::pair<Long64_t,hitInfo*>(tempBinT-timeBinsToRewind,tempEvnr) );
|
|
}
|
|
hitMap.swap(hitMap_TMP);
|
|
}
|
|
|
|
//================================================================
|
|
Bool_t musrCounter::IsInCoincidence(Long64_t timeBin, char motherCounter, Bool_t ignoreHitsAtBinZero, Long64_t timeBinMinimum, Long64_t timeBinMaximum){
|
|
// timeBin ... time bin, at which the coincidence is searched
|
|
// counterTimeShiftOfRequestingCounter ... time shift (in bin units) of the counter, for which the coincidence is searched
|
|
// ignoreHitsAtBinZero ... if "true", hits at timeBin will be ignored (needed for searching of coincidence of M counter
|
|
// with other M counters or P counters with other P counters)
|
|
// "false" should be used for coincidence detectors and vetos.
|
|
if (hitMap.empty()) return false;
|
|
// Long64_t timeBinToTest = timeBin;
|
|
Long64_t timeBinMin;
|
|
Long64_t timeBinMax;
|
|
|
|
// If timeBinMinimum and timeBinMaximum are not specified, use internal time window of the detector (koincidence or veto detectors).
|
|
// Otherwise use timeBinMinimum and timeBinMaximum (e.g.coincidence of a positron counter with other positron counters).
|
|
if (timeBinMinimum!=-123456789) timeBinMin = timeBin + timeBinMinimum; // time window requested through "timeBinMinimum"
|
|
else if (counterType == 'V') timeBinMin = timeBin + antiCoincidenceTimeWindowMin; // this is veto detector
|
|
else if (motherCounter=='M') timeBinMin = timeBin + coincidenceTimeWindowMin_M; // this is coinc. detector (or M counter) connected to M
|
|
else if (motherCounter=='P') timeBinMin = timeBin + coincidenceTimeWindowMin_P; // this is coinc. detector connected to P
|
|
|
|
if (timeBinMaximum!=-123456789) timeBinMax = timeBin + timeBinMaximum; // time window requested through "timeBinMinimum"
|
|
else if (counterType == 'V') timeBinMax = timeBin + antiCoincidenceTimeWindowMax; // this is veto detector
|
|
else if (motherCounter=='M') timeBinMax = timeBin + coincidenceTimeWindowMax_M; // this is coinc. detector (or M counter) connected to M
|
|
else if (motherCounter=='P') timeBinMax = timeBin + coincidenceTimeWindowMax_P; // this is coinc. detector connected to P
|
|
|
|
// Long64_t timeBinMin = (timeBinMinimum==-123456789) ? timeBin + coincidenceTimeWindowMin : timeBin + timeBinMinimum;
|
|
// Long64_t timeBinMax = (timeBinMaximum==-123456789) ? timeBin + coincidenceTimeWindowMax : timeBin + timeBinMaximum;
|
|
for (hitMap_TYPE::iterator it = hitMap.begin(); it != hitMap.end(); ++it) {
|
|
Long64_t timeBinOfCount_tmp = it->first;
|
|
if ((timeBinOfCount_tmp >= timeBinMin) && (timeBinOfCount_tmp <= timeBinMax)) {
|
|
if ((timeBin!=timeBinOfCount_tmp)||(!ignoreHitsAtBinZero)) {
|
|
return true;
|
|
}
|
|
}
|
|
else if (timeBinOfCount_tmp > timeBinMax) return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//================================================================
|
|
Bool_t musrCounter::GetNextGoodMuon(Int_t evtID, Long64_t timeBinMin, Long64_t& timeBinOfNextHit, Int_t& kEntry, Int_t& idet, Int_t& idetID, Double_t& idetEdep, Bool_t& doubleHitFound) {
|
|
// This function searches for a good muon, i.e. the muon
|
|
// 1) belongs to the currently analysed event
|
|
// 2) is in coincidence with all required coincidence detectors
|
|
// 3) is not in coincidence with veto detectors
|
|
// 4) is not in coincidence with other muons (more precisely - with hits in m-counter).
|
|
// INPUT PARAMETERS: evtID, timeBinMin
|
|
// OUTPUT PARAMETERS: timeBinOfNextHit
|
|
//
|
|
// Loop over the hits in the counter
|
|
// std::cout<<" musrCounter::GetNextGoodMuon timeBinMin="<<timeBinMin<<std::endl;
|
|
if (hitMap.empty()) return false;
|
|
if (counterType!='M') {std::cout<<"\n!!! FATAL ERROR !!! musrCounter::GetNextGoodMuon: not the muon counter! ==> S T O P !!!\n"; exit(1);}
|
|
doubleHitFound = false;
|
|
for (hitMap_TYPE::iterator it = hitMap.begin(); it != hitMap.end(); ++it) {
|
|
|
|
Long64_t timeBinOfCount_tmp = it->first;
|
|
timeBinOfNextHit = timeBinOfCount_tmp;
|
|
if (timeBinOfCount_tmp <= timeBinMin) continue; // This hit was already processed previously ==> skip it
|
|
|
|
Int_t eventNumber = (it->second)->eventIDnumber;
|
|
if (eventNumber!=evtID) continue; // This trigger hit does not correspond to the currently processed event
|
|
// ==> skip it, becuase it was already proceesed or will be processed in future
|
|
numberOfMuonCandidates++;
|
|
// std::cout<<"*** "<<evtID<<" eventNumber="<<eventNumber<<" canditas="<<numberOfMuonCandidates<<std::endl;
|
|
// Hit candidate was found. Now check its coincidences and vetos
|
|
for (counterMapType::const_iterator itCounter = koincidenceCounterMap.begin(); itCounter!=koincidenceCounterMap.end(); ++itCounter) {
|
|
if (!( (itCounter->second)->IsInCoincidence(timeBinOfCount_tmp,'M') )) goto endOfThisHit; // no coincidence found ==> skip hit
|
|
}
|
|
for (counterMapType::const_iterator itCounter = vetoCounterMap.begin(); itCounter!=vetoCounterMap.end(); ++itCounter) {
|
|
if ( (itCounter->second)->IsInCoincidence(timeBinOfCount_tmp,'M') ) goto endOfThisHit; // coincidence with veto found ==> skip hit
|
|
}
|
|
|
|
numberOfMuonCandidatesAfterVK++;
|
|
|
|
// Check coincidences with other hits in the M counter
|
|
// it is expected that there is only one M counter
|
|
if (this->IsInCoincidence(timeBinOfCount_tmp,'M',true) ) { // coincidence with another M-counter hit ==> skip hit
|
|
doubleHitFound = true;
|
|
// std::cout<<"UJGUR double hit found"<<std::endl;
|
|
goto endOfThisHit;
|
|
}
|
|
|
|
numberOfMuonCandidatesAfterVKandDoubleHitRemoval++;
|
|
|
|
kEntry = (it->second)->eventEntry;
|
|
idet = (it->second)->det_i;
|
|
idetID = (it->second)->det_id;
|
|
idetEdep = (it->second)->det_edep;
|
|
// timeBinOfNextHit = timeBinOfCount_tmp;
|
|
return true;
|
|
|
|
endOfThisHit:
|
|
continue;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//================================================================
|
|
Int_t musrCounter::GetNextGoodPositron(Int_t evtID, Long64_t timeBinMin, Long64_t timeBinMax, Long64_t& timeBinOfNextGoodHit, Long64_t& timeBinOfNextGoodHit_phaseShifted, Int_t& kEntry, Int_t& idet, Int_t& idetID, Double_t& idetEdep, Bool_t& doubleHitFound) {
|
|
// INPUT PARAMETERS: evtID, timeBinMin
|
|
// OUTPUT PARAMETERS: timeBinOfNextGoodHit
|
|
// positronQuality = 0 ... no positron candidate found
|
|
// = 1 ... positron candidate found, but vetoed or not in a required coincidence with other detector
|
|
// = 2 ... good positron found
|
|
// Loop over the hits in the counter
|
|
Int_t positronQuality=0;
|
|
if (bool_debugingRequired) {if (debugEventMap[evtID]>4) myPrintThisCounter(evtID);}
|
|
if (hitMap.empty()) return 0;
|
|
if (counterType!='P') {std::cout<<"\n!!! FATAL ERROR !!! musrCounter::GetNextGoodPositron: not the positron counter! ==> S T O P !!!\n"; exit(1);}
|
|
doubleHitFound = false;
|
|
for (hitMap_TYPE::iterator it = hitMap.begin(); it != hitMap.end(); ++it) {
|
|
Int_t eventNumber = (it->second)->eventIDnumber;
|
|
Long64_t timeBinOfCount_tmp = it->first;
|
|
if ((timeBinOfCount_tmp <= timeBinMin) || (timeBinOfCount_tmp > timeBinMax)) {
|
|
if (bool_debugingRequired) {
|
|
if (debugEventMap[evtID]>3) {std::cout<<"DEBUGEVENT:"<<evtID<<"\"GetNextGoodPositron\": Hit out of data interval"<<std::endl;}
|
|
}
|
|
continue; // This hit is out of the data interval ==> skip it
|
|
}
|
|
|
|
// Hit candidate was found. Now check its coincidences and vetos
|
|
positronQuality=1;
|
|
for (counterMapType::const_iterator itCounter = koincidenceCounterMap.begin(); itCounter!=koincidenceCounterMap.end(); ++itCounter) {
|
|
if (bool_debugingRequired) {
|
|
if (debugEventMap[evtID]>4) { (itCounter->second)->myPrintThisCounter(evtID); }
|
|
}
|
|
if (!( (itCounter->second)->IsInCoincidence(timeBinOfCount_tmp,'P') )) {
|
|
if (bool_debugingRequired) {
|
|
if (debugEventMap[evtID]>3) {std::cout<<"DEBUGEVENT:"<<evtID<<"\"GetNextGoodPositron\": Coincidence required but not found"<<std::endl;}
|
|
}
|
|
goto endOfThisHit; // no coincidence found ==> skip hit
|
|
}
|
|
}
|
|
for (counterMapType::const_iterator itCounter = vetoCounterMap.begin(); itCounter!=vetoCounterMap.end(); ++itCounter) {
|
|
if ( (itCounter->second)->IsInCoincidence(timeBinOfCount_tmp,'P') ) {
|
|
if (bool_debugingRequired) {
|
|
if (debugEventMap[evtID]>3) {std::cout<<"DEBUGEVENT:"<<evtID<<"\"GetNextGoodPositron\": Coincidence vith veto detector found"<<std::endl;}
|
|
}
|
|
goto endOfThisHit; // coincidence with veto found ==> skip hit
|
|
}
|
|
}
|
|
// Check coincidences with other P counters
|
|
// Coincidences with other P counters must be checked in musrAnalysis.cxx
|
|
//
|
|
// ADD HERE THE CHECK THAT THE POSITRON IS FOUND WITHIN THE DATA INTERVAL, i.e. within <timeBinMin,timeBinMax>.
|
|
// AND ALSO CHECK THAT THIS IS TRUE FOR THE COINCIDENCE WITH OTHER POSITRON COUNTERS!!!
|
|
if (this->IsInCoincidence(timeBinOfCount_tmp,'P',true,timeBinMin,timeBinMax) ) { // coincidence with another P-counter hit ==> skip hit
|
|
if (bool_debugingRequired) {
|
|
if (debugEventMap[evtID]>3) {std::cout<<"DEBUGEVENT:"<<evtID<<"\"GetNextGoodPositron\": Coincidence with other positron candidate in the same counter."<<std::endl;}
|
|
}
|
|
doubleHitFound = true;
|
|
// std::cout<<"tttttttttttttttttttt doubleHitN="<<doubleHitN++<<std::endl;
|
|
goto endOfThisHit;
|
|
}
|
|
|
|
kEntry = (it->second)->eventEntry;
|
|
idet = (it->second)->det_i;
|
|
idetID = (it->second)->det_id;
|
|
idetEdep = (it->second)->det_edep;
|
|
timeBinOfNextGoodHit = timeBinOfCount_tmp;
|
|
timeBinOfNextGoodHit_phaseShifted = (it->second) -> timeBin2;
|
|
if (bool_debugingRequired) {
|
|
if (debugEventMap[evtID]>3) {std::cout<<"DEBUGEVENT:"<<evtID<<"\"GetNextGoodPositron\": Good positron candidate found in this counter."<<std::endl;}
|
|
}
|
|
//cDEL std::cout<<"timeBinOfNextGoodHit ="<<timeBinOfNextGoodHit<<" timeBinOfNextGoodHit_phaseShifted = "<<timeBinOfNextGoodHit_phaseShifted<<std::endl;
|
|
return 2;
|
|
|
|
endOfThisHit:
|
|
;
|
|
// continue;
|
|
}
|
|
return positronQuality;
|
|
}
|
|
|
|
//================================================================
|
|
void musrCounter::SetCoincidenceTimeWindowOfAllCoincidenceDetectors(char motherCounter, Long64_t maxCoinc, Long64_t min, Long64_t max) {
|
|
// std::cout<<"QQQQQQQQQQQQQQQQQQQQQ koincidenceCounterMap.size()="<<koincidenceCounterMap.size()<<std::endl;
|
|
for (counterMapType::const_iterator it = koincidenceCounterMap.begin(); it!=koincidenceCounterMap.end(); ++it) {
|
|
Long64_t maxCoinc_AlreadySet = ((it->second)->GetMaxCoincidenceTimeWindow());
|
|
if (maxCoinc < maxCoinc_AlreadySet) (it->second)->SetMaxCoincidenceTimeWindow(maxCoinc);
|
|
|
|
if (motherCounter=='M') (it->second)->SetCoincidenceTimeWindow_M(min,max);
|
|
else if (motherCounter=='P') (it->second)->SetCoincidenceTimeWindow_P(min,max);
|
|
else {
|
|
std::cout<<"musrCounter::SetCoincidenceTimeWindowOfAllCoincidenceDetectors ERROR: Strange motherCounter "
|
|
<<motherCounter<<"\n ==> S T O P "<<std::endl;
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
//================================================================
|
|
void musrCounter::SetCoincidenceTimeWindowOfAllVetoDetectors(Long64_t maxCoinc, Long64_t min, Long64_t max) {
|
|
for (counterMapType::const_iterator it = vetoCounterMap.begin(); it!=vetoCounterMap.end(); ++it) {
|
|
musrCounter* counter = it->second;
|
|
Long64_t maxCoinc_AlreadySet = counter->GetMaxCoincidenceTimeWindow();
|
|
Long64_t min_AlreadySet = counter->GetAntiCoincidenceTimeWindowMin();
|
|
Long64_t max_AlreadySet = counter->GetAntiCoincidenceTimeWindowMax();
|
|
if (maxCoinc < maxCoinc_AlreadySet) counter->SetMaxCoincidenceTimeWindow(maxCoinc);
|
|
if (min < min_AlreadySet) counter->SetAntiCoincidenceTimeWindowMin(min);
|
|
if (max > max_AlreadySet) counter->SetAntiCoincidenceTimeWindowMax(max);
|
|
}
|
|
}
|
|
|
|
//================================================================
|
|
void musrCounter::myPrintThisCounter(Int_t evtID, Int_t detail) {
|
|
Bool_t eventMixing=false;
|
|
if ((hitMap.begin()==hitMap.end()) && (detail<=1) ) return;
|
|
if (detail>1) std::cout<<"musrCounter::myPrintThisCounter: counterNr = "<<counterNr<<": ";
|
|
else std::cout<<" counter = "<<counterNr<<": ";
|
|
for (hitMap_TYPE::iterator it = hitMap.begin(); it != hitMap.end(); ++it) {
|
|
std::cout<<"\t"<<it->first<<" "<<(it->second)->eventIDnumber<<",";
|
|
if (evtID != (it->second)->eventIDnumber) {eventMixing=true;}
|
|
}
|
|
if (eventMixing) {std::cout<<" Potential event mixing";}
|
|
std::cout<<std::endl;
|
|
}
|
|
|
|
//================================================================
|