Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

CellTrackingTrgEngine - source file

// ESAF : Euso Simulation and Analysis Framework
// $Id: CellTrackingTrgEngine.cc,v 1.10 2005/11/10 10:36:18 pesce 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();//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;
}
About Us | EUSO Official Website | Web pages created by Roberto Pesce and Alessandro Thea - Last Update Wed Nov 16 16:57:39 2005 Wed Nov 16 16:29:22 2005