// ESAF : Euso Simulation and Analysis Framework
// $Id: CellTrackingTrgEngine.cc,v 1.9 2005/05/15 13:19:31 thea Exp $
// M. Pallavicini created Oct, 24 2003
#include "CellTrackingTrgEngine.hh"
#include "MacroCellData.hh"
#include "TROOT.h"
#include "TMarker.h"
#include "TBox.h"
#include "TCanvas.h"
#include "TLine.h"
#include "MacroCell.hh"
#include "MacroCellHit.hh"
#include "FrontEndChip.hh"
#include "Photomultiplier.hh"
#include "PmtGeometry.hh"
#include <string>
ClassImp(CellTrackingTrgEngine)
//______________________________________________________________________________
CellTrackingTrgEngine::CellTrackingTrgEngine() :
TriggerEngine(string("CellTrackingEngine"),kCellTrackingTrigger ) {
//
// Constructor
//
}
//______________________________________________________________________________
CellTrackingTrgEngine::~CellTrackingTrgEngine() {
//
// Destructor
//
}
//______________________________________________________________________________
void CellTrackingTrgEngine::Simulate( MacroCellData *pData ) {
//
// Do simulation
//
//get side of macrocell from config file --> alter to read from object
Int_t l=(Int_t)Conf()->GetNum("CellTrackingTrgEngine.MacroSide");
Bool_t silent=(Bool_t)Conf()->GetNum("CellTrackingTrgEngine.Silent");
if (gROOT->IsBatch()) silent=true;
Bool_t debug=(Bool_t)Conf()->GetNum("CellTrackingTrgEngine.Debug");
//catch a specific macrocell
// if (silent) cout << "M#" << pData->Cell()->Id()<<" "<<flush;
if (!silent)
cout << "MACROCELL # "<<pData->Cell()->Id() <<" num hits="<<pData->NumMacroCellHits()<<endl;
// if (pData->Cell()->Id() !=1) return;
//catch macrocell not empty
if (pData->IsEmpty())
{
//cout << "nothing to do" << endl;
return;
}
//__________________________________OBJECTS
//create object to contain Wired or
//X
vector<vector<Bool_t> > WiredXGTU;
vector<Bool_t> WiredX;
//Y
vector<vector<Bool_t> > WiredYGTU;
vector<Bool_t> WiredY;
//________________________________________
MacroCell *MCPARENT = pData->Cell(); //Parent Macrocell Pointer
if (debug) cout<< "1"<<endl;
//silent variables (display)
Int_t minX;
Int_t maxX;
Int_t minY;
Int_t maxY;
TCanvas* MCD(0);
map<Int_t,TMarker*> PMpix;
if (debug) cout<< "2"<<endl;
if (!silent){
//DISPLAY macrocell
//create canvas
char title [50];
sprintf(title,"Track Find Trigger - Macrocell #%d Display",pData->Cell()->Id());
MCD=new TCanvas("MCDisplay",title,1100,800);
//draw macrocell acording to PMTs
const vector<Photomultiplier*>* PMTS =MCPARENT->Pmts();
//container for pixels : map (UID pixel) vs Pixel
//silent map<Int_t,TMarker*> PMpix;
// get min & max for canvas: start in PMO Pix0
minX=(Int_t)MCPARENT->GetPmt(0)->Geometry()->Position(0)[0]-10;
maxX=(Int_t)MCPARENT->GetPmt(0)->Geometry()->Position(0)[0]+10;
minY=(Int_t)MCPARENT->GetPmt(0)->Geometry()->Position(0)[1]-10;
maxY=(Int_t)MCPARENT->GetPmt(0)->Geometry()->Position(0)[1]+10;
//loop in PMTS
for (Int_t PMTS_i=0;PMTS_i<(Int_t)PMTS->size(); PMTS_i++)
{
//get geometry
Photomultiplier *PMT=(*PMTS)[PMTS_i];
PmtGeometry* PMgeo= PMT->Geometry();
//loop in pixels
for (Int_t PMch=0;PMch<36;PMch++){
double pixX=PMgeo->Position(PMch)[0];
double pixY=PMgeo->Position(PMch)[1];
if (minX>pixX) minX=(Int_t)pixX-20;
if (minY>pixY) minY=(Int_t)pixY-20;
if (maxX<pixX) maxX=(Int_t)pixX+20;
if (maxY<pixY) maxY=(Int_t)pixY+20;
PMpix[PMgeo->GetUniqueId(PMch)]= new TMarker(pixX,pixY,8);
// cout <<"*** "<<PMch << " x="<< pixX << " y="<<pixY<<endl;
PMpix[PMgeo->GetUniqueId(PMch)]->Draw();
}
}
MCD->Range(minX,minY,maxX,maxY);
gPad->SetFillColor(38);
}//end draw macrocell
if (debug) cout<< "3"<<endl;
for(Int_t gtu = pData->GtuStart(); gtu < pData->GtuEnd(); gtu++) //loop nos GTU
{
vector<MacroCellHit*>* hitinhos =pData->Hits(gtu);
//clean wired or for this GTU
WiredX.assign(l,false);
WiredY.assign(l,false);
for (uint hi=0;hi < hitinhos->size();hi++) //loop in hits
{
//construct pixels of macrocell
MacroCellHit *hitin = (*hitinhos)[hi];
Int_t C= hitin->Col();
Int_t R= hitin->Row();
//update wired or
WiredX[C]=true;
WiredY[R]=true;
if (debug) cout<< "3.5"<<endl;
if (!silent){ //draw HITS
Int_t ID = MCPARENT->GetUniqueIdRowCol(R,C);
PMpix[ID]->SetMarkerColor(PMpix[ID]->GetMarkerColor()+1);
PMpix[ID]->Draw();
}//end draw hists
};
WiredXGTU.push_back(WiredX);
WiredYGTU.push_back(WiredY);
if (debug) cout<< "4"<<endl;
//to check buildup of signal
//cout<<gtu<<flush;
if (!silent)
MCD->Update();
//getchar();
if (debug) cout<< "4.1"<<endl;
}
if (!silent){ //DISPLAY
// MCD->Range(minX,minY,maxX,maxY);
gPad->SetFillColor(38);
MCD->Draw();
gPad->WaitPrimitive();
if (debug) cout<< "4.2"<<endl;
//test loop for lines and columns
for (Int_t line=1;line<49;line++) {
for (Int_t column=1;column<49;column++)
{
//cout << "l= "<<line << " c= "<<column <<endl;
Int_t IDTest = MCPARENT->GetUniqueIdRowCol(line,column);
if (debug) cout<< "4.3"<<endl;
if( PMpix.count(IDTest) == 0 ) continue;
PMpix[IDTest]->SetMarkerStyle(28);
PMpix[IDTest]->Draw();
// MCD->Update();
// getchar();
PMpix[IDTest]->SetMarkerStyle(24);
PMpix[IDTest]->Draw();
}
if (debug) cout<< "4.4"<<endl;
MCD->Update();
}
if (debug) cout<< "4.5"<<endl;
}//DISPLAY
// return;
if (debug) cout<< "5"<<endl;
// GTU number
Int_t nGTU = WiredXGTU.size();
if (nGTU==0) {cout<< "######CELLTRACKING NGTU=0"<<endl; return;}
if (!silent) {//display projections:
//X
TCanvas* Xproj=new TCanvas("XwiredOr","Track Find Trigger - X WiredOr",1100,800);
Xproj->Range(-5,-5,l+5,nGTU+5);
vector<vector<TMarker*> > pixWXGTU; //pixeis WXGTU
vector<TMarker*> WX(l); //Pixeis WX
//loop in wired or
for (Int_t G=0;G<(Int_t)WiredXGTU.size();G++)
{
for (Int_t CC=0;CC<(Int_t)WiredXGTU[G].size();CC++)
{
WX[CC]=new TMarker(CC,G,24);
if (WiredXGTU[G][CC]) {
WX[CC]->SetMarkerColor(2);
WX[CC]->SetMarkerStyle(20);
}
WX[CC]->Draw();
}
pixWXGTU.push_back(WX);
}
if (debug) cout<< "6"<<endl;
//Y
TCanvas* Yproj=new TCanvas("YwiredOr","Track Find Trigger - Y WiredOr",1100,800);
Yproj->Range(-5,-5,l+5,nGTU+5);
vector<vector<TMarker*> > pixWYGTU; //pixeis WYGTU
vector<TMarker*> WY(l); //Pixeis WY
//loop in wired or
for (Int_t G=0;G<(Int_t)WiredYGTU.size();G++)
{
for (Int_t RR=0;RR<(Int_t)WiredYGTU[G].size();RR++)
{
WY[RR]= new TMarker(RR,G,24);
if (WiredYGTU[G][RR])
{
WY[RR]->SetMarkerColor(2);
WY[RR]->SetMarkerStyle(20);
}
WY[RR]->Draw();
}
pixWYGTU.push_back(WY);
}
}//display projwct
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++ Start the algorithm ++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (debug) cout<< "7"<<endl;
//variables
// C register
vector <Bool_t> CX; // *Macrocell Side
vector <Bool_t> CY;
//next -> DX,DY
vector <Bool_t> DX;
vector <Bool_t> DY;
// L register
vector <Bool_t> LX;
vector <Bool_t> LY;
//next -> DX,DY
vector <Bool_t> MX;
vector <Bool_t> MY;
//stair left
vector<vector<Bool_t> > SLX;
vector<vector<Bool_t> > SLY;
// R register
vector <Bool_t> RX;
vector <Bool_t> RY;
//next -> DX,DY
vector <Bool_t> SX;
vector <Bool_t> SY;
//stair Right
vector<vector<Bool_t> > SRX;
vector<vector<Bool_t> > SRY;
// Time register
vector <Bool_t> XT;
vector <Bool_t> YT;
vector <Bool_t> XYT;
//auxiliar:
// number of GTUS --> nGTU
// side of macrocell: -->l
// X projections X GTU -->WiredXGTU
// Y projections X GTU -->WiredYGTU
if (debug) cout<< "7.5"<<endl;
if (debug) cout<< "nGTU="<<nGTU<<endl;
//prepare the time registers
XT.assign(nGTU-1,false);
if (debug) cout<< "7.51"<<endl;
YT.assign(nGTU-1,false);
if (debug) cout<< "7.52"<<endl;
XYT.assign(nGTU-1,false);
if (debug) cout<< "8"<<endl;
// trigger loop
//__________________________________________________
//CX register
CX=WiredXGTU[0];
for (Int_t cGTU=1 ; cGTU<nGTU ; cGTU++)
{
DX = WiredXGTU[cGTU];
//print cx
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i1=0;i1<CX.size();i1++) cout << CX[i1];
//dbg cout <<" <-- CX"<< endl;
//print dx
//dbg cout<<endl <<" ## DX=";
//dbg for (Int_t i2=0;i2<DX.size();i2++) cout << DX[i2];
//dbg cout <<" <-- DX"<< endl;
CX = VecBitAnd(DX,CX);
//print cxafter -->re
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i3=0;i3<CX.size();i3++) cout << CX[i3];
//dbg cout <<" <-- result"<< endl;
//dbg cout << "ISEMPTY? --> "<< VecEmpty(CX)<< endl;
if (!VecEmpty(CX))
CX = DX;
else XT[cGTU-1]=true;
//dbg getchar();
}
if (debug) cout<< "9"<<endl;
//__________________________________________________
//LX register
// shift to the left;"create stairway register"
//the shift is circular then a line to the right is a center line
SLX=WiredXGTU;
for (Int_t SL1=1;SL1<(Int_t)SLX.size();SL1++)
{
for (Int_t SL2=SL1;SL2<(Int_t)SLX.size();SL2++)
{
SLX[SL2]=VecShift(SLX[SL2],-1);
}
}
//detect the center line on SLX register
LX=SLX[0];
for (Int_t cGTU=1 ; cGTU<nGTU ; cGTU++)
{
MX = SLX[cGTU];
//print cx
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i1=0;i1<CX.size();i1++) cout << CX[i1];
//dbg cout <<" <-- CX"<< endl;
//print dx
//dbg cout<<endl <<" ## DX=";
//dbg for (Int_t i2=0;i2<DX.size();i2++) cout << DX[i2];
//dbg cout <<" <-- DX"<< endl;
LX = VecBitAnd(MX,LX);
//print cxafter -->re
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i3=0;i3<CX.size();i3++) cout << CX[i3];
//dbg cout <<" <-- result"<< endl;
//dbg cout << "ISEMPTY? --> "<< VecEmpty(CX)<< endl;
if (!VecEmpty(LX))
LX = MX;
else XT[cGTU-1]=true;
//dbg getchar();
}
if (debug) cout<< "10"<<endl;
//____________________________________________________________________
//RX register
// shift to the RIGHT;"create stairway register"
//the shift is circular then a line to the LEFT is a center line
SRX=WiredXGTU;
for (Int_t SR1=1;SR1<(Int_t)SRX.size();SR1++)
{
for (Int_t SR2=SR1;SR2<(Int_t)SRX.size();SR2++)
{
SRX[SR2]=VecShift(SRX[SR2],1);
}
}
//detect the center line on SRX register
RX=SRX[0];
for (Int_t cGTU=1 ; cGTU<nGTU ; cGTU++)
{
SX = SRX[cGTU];
//print cx
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i1=0;i1<CX.size();i1++) cout << CX[i1];
//dbg cout <<" <-- CX"<< endl;
//print dx
//dbg cout<<endl <<" ## DX=";
//dbg for (Int_t i2=0;i2<DX.size();i2++) cout << DX[i2];
//dbg cout <<" <-- DX"<< endl;
RX = VecBitAnd(SX,RX);
//print cxafter -->re
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i3=0;i3<CX.size();i3++) cout << CX[i3];
//dbg cout <<" <-- result"<< endl;
//dbg cout << "ISEMPTY? --> "<< VecEmpty(CX)<< endl;
if (!VecEmpty(RX))
RX = SX;
else XT[cGTU-1]=true;
//dbg getchar();
}
if (debug) cout<< "11"<<endl;
//________________________________________________________
//CY register
CY=WiredYGTU[0];
for (Int_t cGTU=1 ; cGTU<nGTU ; cGTU++)
{
DY = WiredYGTU[cGTU];
CY = VecBitAnd(DY, CY);
if (!VecEmpty(CY))
CY = DY;
else YT[cGTU-1]=true;
}
if (debug) cout<< "12"<<endl;
//__________________________________________________
//LY register
// shift to the left;"create stairway register"
//the shift is circular then a line to the right is a center line
SLY=WiredYGTU;
for (Int_t SL1=1;SL1<(Int_t)SLY.size();SL1++)
{
for (Int_t SL2=SL1;SL2<(Int_t)SLY.size();SL2++)
{
SLY[SL2]=VecShift(SLY[SL2],-1);
}
}
//detect the center line on SLY register
LY=SLY[0];
for (Int_t cGTU=1 ; cGTU<nGTU ; cGTU++)
{
MY = SLY[cGTU];
//print cx
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i1=0;i1<CX.size();i1++) cout << CX[i1];
//dbg cout <<" <-- CX"<< endl;
//print dx
//dbg cout<<endl <<" ## DX=";
//dbg for (Int_t i2=0;i2<DX.size();i2++) cout << DX[i2];
//dbg cout <<" <-- DX"<< endl;
LY = VecBitAnd(MY,LY);
//print cxafter -->re
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i3=0;i3<CX.size();i3++) cout << CX[i3];
//dbg cout <<" <-- result"<< endl;
//dbg cout << "ISEMPTY? --> "<< VecEmpty(CX)<< endl;
if (!VecEmpty(LY))
LY = MY;
else YT[cGTU-1]=true;
//dbg getchar();
}
if (debug) cout<< "13"<<endl;
//____________________________________________________________________
//RY register
// shift to the RIGHT;"create stairway register"
//the shift is circular then a line to the LEFT is a center line
SRY=WiredYGTU;
for (Int_t SR1=1;SR1<(Int_t)SRY.size();SR1++)
{
for (Int_t SR2=SR1;SR2<(Int_t)SRY.size();SR2++)
{
SRY[SR2]=VecShift(SRY[SR2],1);
}
}
//detect the center line on SRY register
RY=SRY[0];
for (Int_t cGTU=1 ; cGTU<nGTU ; cGTU++)
{
SY = SRY[cGTU];
//print cx
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i1=0;i1<CX.size();i1++) cout << CX[i1];
//dbg cout <<" <-- CX"<< endl;
//print dx
//dbg cout<<endl <<" ## DX=";
//dbg for (Int_t i2=0;i2<DX.size();i2++) cout << DX[i2];
//dbg cout <<" <-- DX"<< endl;
RY = VecBitAnd(SY,RY);
//print cxafter -->re
//dbg cout<<endl <<" ## CX=";
//dbg for (Int_t i3=0;i3<CX.size();i3++) cout << CX[i3];
//dbg cout <<" <-- result"<< endl;
//dbg cout << "ISEMPTY? --> "<< VecEmpty(CX)<< endl;
if (!VecEmpty(RY))
RY = SY;
else YT[cGTU-1]=true;
//dbg getchar();
}
if (debug) cout<< "14"<<endl;
//__________________________________________________
//generate the trigger if "YT and XT" contain more than "n" consecutive "true". n is the persistency
// XT and YT
XYT=VecBitAnd(XT,YT);
if (!silent)
for (Int_t temp1=0 ; temp1<(Int_t) YT.size() ; temp1++)
{cout << "## "<< temp1<< " -XT-> "<< XT[temp1] << " -YT-> "<<YT[temp1]<< " -XYT-> "<< XYT[temp1]<<endl;}
//count the XYT
Int_t TrackTh=(Int_t)Conf()->GetNum("CellTrackingTrgEngine.Persistency")-1;
Int_t AuxCount=0;
if (!silent) cout<<endl<<"Required Track «"<<TrackTh<<"»"<<endl;
for (Int_t temp2=0 ; temp2<(Int_t) XYT.size() ; temp2++)
{
AuxCount= (AuxCount+(Int_t) XYT[temp2])*(Int_t)XYT[temp2];
if (!silent) cout<< AuxCount;
if (AuxCount >= TrackTh)
{
SetTrigger(true);//GENERATE THE TRIGGER
SetGtuTrigger( pData->GtuStart()+1+temp2 );
cout << endl<<"=== TRIGGER! Cell:" << pData->Cell()->Id()
<< " Gtu:" << pData->GtuStart()+1+temp2 << " Engine:" << GetName() << endl;
return;
}
}
if (debug) cout<< "15"<<endl;
}
//______________________________________________________________________________
vector<Bool_t> CellTrackingTrgEngine::VecBitAnd(vector<Bool_t> A, vector<Bool_t> B) {
//
// routine to and registers
//
//test the registers
if (A.size() != B.size() )
cout << "EERRRRRRRRRRRROOOOOOOOOOOOOOOOORRRRRRRRRRRRRRR in BitAnd in CelltrackingTrigger";
Int_t s = A.size();
vector<Bool_t> OUT;
OUT.assign(s,false);
for (Int_t i =0; i<s;i++)
{
OUT[i] = A[i] && B[i];
}
return OUT;
}
Bool_t CellTrackingTrgEngine::VecEmpty (vector<Bool_t> A) {
//
// Routine to check register is empty
//
Int_t s = A.size();
Bool_t OUT;
OUT=false;
for (Int_t i =0; i<s;i++)
{
OUT = A[i] || OUT;
}
return OUT;
}
//______________________________________________________________________________
vector<Bool_t> CellTrackingTrgEngine::VecShift(vector<Bool_t> vec, Int_t shift)
{
// Routine to shift register
// 0 - do not shift
// 1 - shift one to the right
// -1 - shift one to the left
//-1 shift left
//0 nothing
// 1 shift right
Bool_t temp;
switch(shift) {
case -1 :
temp=vec[0];
for (Int_t i=1; i<(Int_t) vec.size();i++)
vec[i-1]=vec[i];
vec[vec.size()-1]=temp;
break;
case 0 :
break;
case 1 :
temp=vec[vec.size()-1];
for (Int_t i=(Int_t)vec.size()-1; i>-1;i--)
vec[i+1]=vec[i];
vec[0]=temp;
break;
default : throw runtime_error("CellTracking: ERROR");
}
return vec;
}