Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

LblChipTrackingTrgEngine - source file

// ESAF : Euso Simulation and Analysis Framework
// $Id: LblChipTrackingTrgEngine.cc,v 1.2 2005/01/26 10:08:14 thea Exp $

#include "LblChipTrackingTrgEngine.hh"
#include "MacroCellData.hh"
#include "MacroCell.hh"
#include "ElementaryCell.hh"
#include "FrontEndChip.hh"
#include "BoolAlgebra.hh"
// #include "ChipTrackSegment.hh" Put this back in later

ClassImp(LblChipTrackingTrgEngine)

//______________________________________________________________________________
LblChipTrackingTrgEngine::LblChipTrackingTrgEngine() : 
TriggerEngine(string("LblChipTrackingTrgEngine"), kLblChipTrackingTrigger ) {

    // constructor

    // Read all the control flags from the LblChipTrackingTrgEngine.cfg file

    // First the flag to control which pxiels get used to make track segments
    fPxlthr = (Int_t)Conf()->GetNum("LblChipTrackingTrgEngine.Pxlthr");

    // Now the flags to control how track segments are found
    fColumn = (Int_t)Conf()->GetNum("LblChipTrackingTrgEngine.Column");
    fColthr = (Int_t)Conf()->GetNum("LblChipTrackingTrgEngine.Colthr");
    fFrmsinseg = (Int_t)Conf()->GetNum("LblChipTrackingTrgEngine.Frmsinseg");
    fSegs = (Int_t)Conf()->GetNum("LblChipTrackingTrgEngine.Segs");
    fTrksumthr = (Int_t)Conf()->GetNum("LblChipTrackingTrgEngine.Trksumthr");
    fWantsumsub = (bool)Conf()->GetNum("LblChipTrackingTrgEngine.Wantsumsub");

    // Next the flags to control how segments are joined to form tracks
    // and tracks are tested for persistency
    fFrmsinpsum = (Int_t)Conf()->GetNum("LblChipTrackingTrgEngine.Frmsinpsum");
    fMinpersum = (Int_t)Conf()->GetNum("LblChipTrackingTrgEngine.Minpersum");

    // Finally the flags to control the level of output messages
    fVerbose = (bool)Conf()->GetNum("LblChipTrackingTrgEngine.Verbose");
    fDebug = (bool)Conf()->GetNum("LblChipTrackingTrgEngine.Debug");

    if (fVerbose) {
	Msg(EsafMsg::Info) << "fPxlthr = " << fPxlthr << MsgDispatch;

	Msg(EsafMsg::Info) << "fColumn = " << fColumn << MsgDispatch;
	Msg(EsafMsg::Info) << "fColthr = " << fColthr << MsgDispatch;
	Msg(EsafMsg::Info) << "fFrmsinseg = " << fFrmsinseg << MsgDispatch;
	Msg(EsafMsg::Info) << "fSegs = " << fSegs << MsgDispatch;
	Msg(EsafMsg::Info) << "fTrksumthr = " << fTrksumthr << MsgDispatch;
	Msg(EsafMsg::Info) << "fWantsumsub = " << fWantsumsub << MsgDispatch;

	Msg(EsafMsg::Info) << "fFrmsinpsum = " << fFrmsinpsum << MsgDispatch;
	Msg(EsafMsg::Info) << "fMinpersum = " << fMinpersum << MsgDispatch;

	Msg(EsafMsg::Info) << "fDebug = " << fDebug << MsgDispatch;
    }

}


//______________________________________________________________________________
LblChipTrackingTrgEngine::~LblChipTrackingTrgEngine() {
    
    // dtor
}


//______________________________________________________________________________
 void LblChipTrackingTrgEngine::Simulate( MacroCellData* pData) {    

    // simulate chip tracking algorithm
    if (fVerbose)
	Msg(EsafMsg::Info) << "CHIP TRACKING STARTED MACROCELL " << pData->Cell()->Id() << MsgDispatch;

    // Get maps of ChipGtuData for this MacroCell
    // m1 is a reference (i.e. a short alias) for pData->fChipData2
    // fChipData2 is a map: first element is the Id of this Front End
    //                      second element is a pointer to a second map
    map<Int_t, map<Int_t,ChipGtuData*>* > &m1 = pData->fChipData2;
    map<Int_t, map<Int_t,ChipGtuData*>* >::const_iterator it1;
    Int_t ncells = m1.size();
    if (fVerbose)
	Msg(EsafMsg::Info) << "MacroCell contains " << ncells << " Elementary Cells" << MsgDispatch;

    // Quit if there is no data in this map element
    if (!ncells) return;

    // Now do the main loop over the Elementary Cells, find segments and tracks
    // then look for persistency.
    for (it1=m1.begin(); it1!=m1.end(); it1++) {

	if (fVerbose)
	    Msg(EsafMsg::Info) << "Procesing Elementary Cell " << it1->first << MsgDispatch;

	// Get maps of ChipGtuData for this specific Elementary Cell
	// m2 is a reference to the map object that it1->second points to
	// This map has 2 elements: first element is GTU number
	//                          second element is a pointer to ChipGtuData for this GTU
	map<Int_t,ChipGtuData*> &m2 = *(it1->second);
	map<Int_t,ChipGtuData*>::const_iterator it2;

	// Check to see if this Elementary Cell has enough GTUs
	it2 = m2.begin();
	Int_t first_gtu = it2->first;
	it2 = m2.end();
	it2--;
	Int_t last_gtu = it2->first;
	Int_t gtot = last_gtu - first_gtu + 1;
	if (fVerbose) Msg(EsafMsg::Info) << "First GTU = " << first_gtu << " Last GTU = " << last_gtu << " Elementary Cell contains " << gtot << " GTUs" << MsgDispatch;
	if (last_gtu >= 200) {
	    if (fVerbose) Msg(EsafMsg::Info) << "Last GTU is too late" << MsgDispatch;
	    continue;
	}
	if (gtot < (fSegs*fFrmsinseg)) {
	    if (fVerbose) Msg(EsafMsg::Info) << "Not enough GTUs in this Elementary Cell" << MsgDispatch;
	    continue;
	}

	// Get the number of channels in this chip from the first GTU
	it2 = m2.begin();
	Int_t chan = (it2->second)->FrontEnd()->Channels();
	Int_t NPIX = (it2->second)->FrontEnd()->NumSide();
	if (fDebug)
	    Msg(EsafMsg::Debug) << "Number of channels is " << chan << " Number per side is " << NPIX << MsgDispatch;

	// Zero the arrays
	Clear(last_gtu,NPIX);

	// Find the tracks and segments
	Find_Tracks(m2,last_gtu,chan,NPIX);

	// Check to see if there is a good track
	Check_Persistency(last_gtu,NPIX);

    } // End of it1 loop over Elementary Cells

}

//______________________________________________________________________________
 void LblChipTrackingTrgEngine::Clear(Int_t last_gtu,Int_t NPIX) {
    
    // Clear the fSums and fPers arrays
    for (Int_t i=0; i<(last_gtu+1); i++) {
	for (Int_t j=0; j<NPIX; j++) {
	    for (Int_t k=0; k<NPIX; k++) {
		fSums[i][j][k] = 0;
		fPers[i][j][k] = 0;
	    }
	}
    }
}


//______________________________________________________________________________
 void LblChipTrackingTrgEngine::Find_Tracks(map<Int_t,ChipGtuData*> &m2,Int_t last_gtu,Int_t chan,Int_t NPIX) {

    Int_t gt;
    Int_t last_track_gtu;
    Int_t row;
    Int_t col;
    Int_t colsum;
    Int_t sub_row;
    Int_t sub_col;
    Int_t sub_chan;
    ChipGtuData* gtus;
    Int_t seg1sum;
    Int_t seg2sum;
    Int_t seg3sum;
    Int_t trksum;
    Int_t row_l;
    Int_t row_h;
    Int_t col_l;
    Int_t col_h;
    Int_t sub_row2;
    Int_t sub_col2;

    if (fDebug) {
	Msg(EsafMsg::Debug) << "Number of channels is " << chan << " Number per side is " << NPIX << MsgDispatch;
	Msg(EsafMsg::Debug) << "last_gtu = " << last_gtu << MsgDispatch;
    }

    // Create the iterator for this map
    // it2 is used to loop over all GTUs
    map<Int_t,ChipGtuData*>::const_iterator it2;

    // Main loop over GTUs
    for (it2=m2.begin(); it2!=m2.end(); it2++) {

	// Get the data for this specific GTU
	gt = it2->first;
	gtus = it2->second;
	if (fDebug)
	    Msg(EsafMsg::Debug) << "Building Segments starting at GTU Number " << gt << MsgDispatch;

	// Add this data to the sums for each pixel
	for (Int_t nchan=0; nchan<chan; nchan++) {

	    row = gtus->FrontEnd()->Row(nchan);
	    col = gtus->FrontEnd()->Column(nchan);

	    // Now calculate the sums
	    switch (fColumn) {
	    case 2:
		colsum = 0;
		for (Int_t i=0; i<2; i++) {
		    sub_row = row+i;
		    for (Int_t j=0; j<2; j++) {
			sub_col = col+j;
			if ((sub_row<NPIX)&&(sub_col<NPIX)) {
			    sub_chan = gtus->FrontEnd()->ChanRowCol(sub_row,sub_col);
			    if (gtus->GetCounter(sub_chan) > fPxlthr) {
				colsum += gtus->GetCounter(sub_chan);
			    }
			}
		    }
		}
		break;
	    case 3:
		colsum = 0;
		for (Int_t i=0; i<3; i++) {
		    sub_row = row+i;
		    for (Int_t j=0; j<3; j++) {
			sub_col = col+j;
			if ((sub_row<NPIX)&&(sub_col<NPIX)) {
			    sub_chan = gtus->FrontEnd()->ChanRowCol(sub_row,sub_col);
			    if (gtus->GetCounter(sub_chan) > fPxlthr) {
				colsum += gtus->GetCounter(sub_chan);
			    }
			}
		    }
		}
		break;
	    default:
		colsum = 0;
		// Get this pixel's counts, but only if # counts > threshold
		if (gtus->GetCounter(nchan) > fPxlthr)
		    colsum += gtus->GetCounter(nchan);
		break;
	    } // End of switch (fColumn)

	    // Loop over active segments and add in this column
	    Int_t num_active = ((gt+1)<fFrmsinseg) ? (gt+1) : fFrmsinseg;
	    for (Int_t active=0; active<num_active; active++) {
		fSums[gt-active][row][col] += (colsum>fColthr) ? colsum : 0;
	    }

	} // End of nchan loop over Channels (i.e. Pixels)

    } // End of loop over map m2. At this point we have the sums for each pixel for all GTUs.

    // Now subtract off the background counts, if the fWantsumsub flag is set
    if (fWantsumsub) {
	for (gt=0; gt<(last_gtu+1); gt++) {
	    for (row=0; row<NPIX; row++) {
		for (col=0; col<NPIX; col++) {
		    sub_row = (row + 4)%NPIX;
		    sub_col = (col + 4)%NPIX;
		    Int_t sumsub = fSums[gt][row][col] - fSums[gt][sub_row][sub_col];
		    fSums[gt][row][col] = (sumsub>0) ? sumsub : 0;
		}
	    }
	}
    }

    // Now work with partial sums to find tracksums
    last_track_gtu = (last_gtu+1) - (fSegs*fFrmsinseg);
    for (gt=0; gt<(last_track_gtu+1); gt++) {
	for (row=0; row<NPIX; row++) {
	    for (col=0; col<NPIX; col++) {

		seg1sum = fSums[gt][row][col];

		// Single segment tracks
		if (fSegs == 1) {
		    trksum = seg1sum;
		    if (trksum > fTrksumthr) {
			fPers[gt][row][col] += 1;
			if (fDebug) {
			    Msg(EsafMsg::Debug) << "trksum " << trksum << " > thr " << fTrksumthr << " for single segment track, fPers = " << fPers[gt][row][col] << MsgDispatch;
			    Msg(EsafMsg::Debug) << "Single segment start-GTU = " << gt << " start-Row = " << row << " start-Col = " << col << MsgDispatch;
			}
		    }
		}

		// Two-or-more segment tracks
		if (fSegs >= 2) {
		    row_l = (row>0)        ? row-1 : 0;
		    row_h = (row<(NPIX-1)) ? row+1 : (NPIX-1);
		    col_l = (col>0)        ? col-1 : 0;
		    col_h = (col<(NPIX-1)) ? col+1 : (NPIX-1);

		    for (sub_row=row_l; sub_row<=row_h; sub_row++) {
			for (sub_col=col_l; sub_col<=col_h; sub_col++) {
			    
			    seg2sum = fSums[gt+fFrmsinseg][sub_row][sub_col];

			    // Two segment tracks
			    if (fSegs == 2) {
				trksum = seg1sum + seg2sum;
				if (trksum > fTrksumthr) {
				    fPers[gt][row][col] += 1;
				    if (fDebug) {
					Msg(EsafMsg::Debug) << "trksum " << trksum << " > thr " << fTrksumthr << " for two segment track" << MsgDispatch;
					Msg(EsafMsg::Debug) << "First  segment start-GTU = " << gt << " start-Row = " << row << " start-Col = " << col << MsgDispatch;
					Msg(EsafMsg::Debug) << "Second segment start-GTU = " << gt+fFrmsinseg << " start-Row = " << sub_row << " start-Col = " << sub_col << MsgDispatch;
				    }
				}
			    }

			    // Three segment tracks
			    if (fSegs == 3) {
				// Find sub_row2 and sub_col2 of 3rd segment by straight
				// line extrapolation from row/col and sub_row/sub_col
				sub_row2 = sub_row + (sub_row - row);
				if ((sub_row2 < 0) || (sub_row2 >= NPIX)) continue;
				sub_col2 = sub_col + (sub_col - col);
				if ((sub_col2 < 0) || (sub_col2 >= NPIX)) continue;

				seg3sum = fSums[gt+(2*fFrmsinseg)][sub_row2][sub_col2];

				trksum = seg1sum + seg2sum + seg3sum;
				if (trksum > fTrksumthr) {
				    fPers[gt][row][col] += 1;
				    if (fDebug) {
					Msg(EsafMsg::Debug) << "trksum " << trksum << " > thr " << fTrksumthr << " for three segment track" << MsgDispatch;
					Msg(EsafMsg::Debug) << "First  segment start-GTU = " << gt << " start-Row = " << row << " start-Col = " << col << MsgDispatch;
					Msg(EsafMsg::Debug) << "Second segment start-GTU = " << gt+fFrmsinseg << " start-Row = " << sub_row << " start-Col = " << sub_col << MsgDispatch;
					Msg(EsafMsg::Debug) << "Third  segment start-GTU = " << (gt+(2*fFrmsinseg)) << " start-Row = " << sub_row2 << " start-Col = " << sub_col2 << MsgDispatch;
				    }
				}
			    } // End of fSegs == 3 if statement

			} // End of sub_col loop
		    } // End of sub_row loop
		} // End of fSegs >= 2 if statement
	    } // End of col loop
	} // End of row loop
    } // End of gt loop over all GTUs 
    
}


//______________________________________________________________________________
 void LblChipTrackingTrgEngine::Check_Persistency(Int_t last_gtu,Int_t NPIX) {
    Int_t persum;
    Int_t maxpsum;
    Int_t gtutrig;
    bool above;
    bool lastabove;
    
    if (fDebug)
	Msg(EsafMsg::Debug) << "last_gtu = " << last_gtu << " NPIX = " << NPIX << MsgDispatch;

    for (Int_t row=0; row<NPIX; row++) {
	for (Int_t col=0; col<NPIX; col++) {
	    maxpsum = 0;
	    gtutrig = 0;
	    lastabove = false;

	    for (Int_t gtu=(fFrmsinpsum-1); gtu<(last_gtu+1); gtu++) {

		persum = 0;
		for (Int_t i=0; i<fFrmsinpsum; i++) {
		    if (fPers[gtu-i][row][col] > 0) {
			persum++;
			if (fDebug) Msg(EsafMsg::Debug) << "GTU " << gtu << " Row " << row << " Column " << col << " persum " << persum << MsgDispatch;
		    }
		}

		above = false;
		if (persum >= fMinpersum) {
		    above = true;
		    if (fDebug) {
			Msg(EsafMsg::Debug) << "GTU " << gtu << " Row " << row << " Column " << col << MsgDispatch;
			Msg(EsafMsg::Debug) << "persum " << persum << " >= fMinpersum " << fMinpersum << MsgDispatch;
		    }
		    if (persum > maxpsum) {
			maxpsum = persum;
			gtutrig = gtu;
		    }
		}

		if (!above && lastabove) {
		    SetTrigger( true );
		    SetGtuTrigger(gtutrig);
		    maxpsum = 0;
		    gtutrig = 0;
		    if (fVerbose) {
			Msg(EsafMsg::Info) << "Track has ended, GENERATING TRIGGER" << MsgDispatch;
		    }
		}

		lastabove = above;
	    } // End of gtu loop
	} // End of col loop
    } // End of row loop
}


About Us | EUSO Official Website | Web pages created by Roberto Pesce and Alessandro Thea - Last Update 14-May-2005 21:31