Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

MacroCell - source file

// class MacroCell
// M. Pallavicini - created  20-5-01
//

#include <iostream>
#include <math.h>

#include "euso.hh"
#include "MacroCell.hh"
#include "FrontEndChip.hh"
#include "Config.hh"
#include "ChipGtuData.hh"
#include "MacroCellData.hh"
#include "Photomultiplier.hh"
#include "MacroCellGeometry.hh"

ClassImp(MacroCell)

Int_t MacroCell::gCellCounter = 1;

map<ETriggerTypeIdentifier,TriggerEngine*> *MacroCell::fEngines=0;
  
//______________________________________________________________________________
MacroCell::MacroCell(Int_t rows, Int_t columns) : 
    EsafConfigurable(), fRows(rows), fCols(columns) {
    //
    // Constructor (needs number of rows and columns)
    //

    fCellId = gCellCounter++;
    if ( GetRows()<=0 || GetColumns()<=0) {
        Msg(EsafMsg::Warning) << "Error building macrocell " 
                              << fCellId << MsgDispatch;
        Msg(EsafMsg::Warning) << "Invalid Rows or Columns (" << rows << " "
                              << columns << ")" << MsgDispatch;
    }

    fGtuLength =  Conf()->GetNum("MacroCell.fGtuTimeLength");
    
    fLogicEnabled = Conf()->GetBool("MacroCell.fLogicEnabled");

    // trigger parameters and algorythms
    fTriggerThreshold = (Int_t)Conf()->GetNum("MacroCell.fTriggerThreshold");
    fTriggerType = (ETriggerTypeIdentifier)Conf()->GetNum("MacroCell.fTriggerType");
    if ( !fEngines )
        fEngines = &(TriggerEngine::GetEngines( fTriggerType ) );
    
    // reset arrays and maps
    fPmts.clear();
    fECs.clear();
    fECRowColMap.clear();

}

//______________________________________________________________________________
 MacroCell::~MacroCell() {
    // 
    // Destructor does nothing
    //
}

//______________________________________________________________________________
 Double_t MacroCell::FirstHitTime() {
    // 
    // Compute the time of the first hit in the macrocell
    // 
    Double_t start_event = HUGE;
    for(size_t i=0; i < fECs.size(); i++) {
        if ( fECs[i] ) {
            Double_t t = fECs[i]->FrontEnd()->FirstHitTime();
            if ( t < start_event )
                start_event = t;
        }
    }    
    return start_event;
}

//______________________________________________________________________________
 Double_t MacroCell::LastHitTime() {
    // 
    // Compute the time of the last hit in the macrocell
    //
    Double_t end_event = -HUGE;
    for(size_t i=0; i < fECs.size(); i++) {
        if ( fECs[i] ) {
            Double_t t = fECs[i]->FrontEnd()->LastHitTime();
            if ( t > end_event )
                end_event = t;
        }
    }
    return end_event;
}

//______________________________________________________________________________
 FrontEndChip* MacroCell::FrontEnd(Int_t r, Int_t c) {
    // 
    // Returns a pointer to the front end chip in row r and column c returns
    // NULL if it is not a valid position even if r,c are valid, return value
    // may be NULL with non-squared macrocells
    //
	if ( IsValid(r,c) ) {
		if ( fECRowColMap[RowColId(r,c)] ) {
			return fECRowColMap[RowColId(r,c)]->FrontEnd();
		}
	}
	return (FrontEndChip*)NULL;
}

//______________________________________________________________________________
 Bool_t MacroCell::Add(ElementaryCell* ec, Int_t row, Int_t col) {
    // 
    // Add an elementary cell to this macrocell in position i and j
    // returns true if ok, false on error
    //
	if ( !IsValid(row,col) ) {
		Msg(EsafMsg::Panic) << "Wrong row/col Row "<<row<< " " << GetRows() 
                            << " Col:" << col << " " << GetColumns() << MsgDispatch;
	}

	if ( !ec )
		Msg(EsafMsg::Panic) << "Invalid EC pointer in MacroCell::Add" << MsgDispatch;

	if ( FrontEnd(row,col) )
		Msg(EsafMsg::Panic) << "MacroCell::Add()  Row,Col already associated" << MsgDispatch;

	if (!ec->FrontEnd())
		Msg(EsafMsg::Panic) << "Null Front End pointer in MacroCell::Add" << MsgDispatch;

	// associate all channels to the right row and column
	fECs.push_back( ec );
	for(Int_t i=0; i < ec->FrontEnd()->NumSide(); i++) {
		int r = row+i;
		for(Int_t j=0; j < ec->FrontEnd()->NumSide(); j++) {
			int c = col+j;
            SetECRowCol(ec,row,col);
			pair<int,int> p(r,c);
			fUidRowCol[p]=ec->FrontEnd()->UniqueChanId( ec->FrontEnd()->ChanRowCol(i,j) );
			fRowColUid[ec->FrontEnd()->UniqueChanId( ec->FrontEnd()->ChanRowCol(i,j) )] = p;
        }
    }
    ec->FrontEnd()->SetCellRowColOffset( row, col );
    
    // get pmt pointers
    for(Int_t i=1; i <= ec->GetNumPmts(); i++) {
        fPmts.push_back( ec->GetPmt( i ) );
    }

    // compute new geometry area covered by this macrocell
    Geometry()->Compute();
    
    return kTRUE;
}

//______________________________________________________________________________
 Bool_t MacroCell::CheckPmtState() const {
    // 
    // Check if all pmts of this macrocell are ready
    // (user must have called Simulate for each of them)
    // 
    for( size_t i=0; i < fPmts.size(); i++) { 
        Photomultiplier* pPmt = fPmts[i];
        if ( pPmt ) {
            if ( pPmt->Status() == kPmtFilling ) 
	        pPmt->Simulate();
        } else {
            Msg(EsafMsg::Panic) << "NULL Pmt pointer in CheckPmtState()" << MsgDispatch;
        }
    }
    return kTRUE;
}

//______________________________________________________________________________
 Bool_t MacroCell::IsEmpty() const {
    // returns true if there were not hits in the macrocell or if there is low
    // signal (threshold set by EusoElectronics)     
    if (fLowSignalThreshold <= 0) { 
        for( size_t i=0; i < fPmts.size(); i++) { 
            Photomultiplier* pPmt = fPmts[i];
            if ( pPmt ) {
                if ( !pPmt->IsEmpty() )
	            return kFALSE;
            } else {
	            Msg(EsafMsg::Panic) << "NULL Pmt pointer in CheckPmtState()" << MsgDispatch;
            }
        }
        return kTRUE;
    } else { //if  ( fLowSignalThreshold > 0 ) {
        Int_t numSignals(0);
        for( size_t i=0; i < fPmts.size(); i++) { 
            Photomultiplier* pPmt = fPmts[i];
            if ( pPmt ) {
                for ( Int_t ch=0; ch < pPmt->NumChan(); ch++ ) {
                    vector<PmtSignal*>* sigs = &(pPmt->Signals(ch));
                    if ( sigs ) {
                        for(UInt_t iSig=0; iSig < sigs->size(); iSig++) {
                            PmtSignal *s = (*sigs)[iSig];
                            if ( s ) {
                                numSignals++;
                            }
                        }
                    }
                }
            }
        }
        return ( numSignals <= fLowSignalThreshold );
    } 
    
    /*
      else {
        FatalError("Wrong LowSignalThreshold Assignment");
        return kFALSE;
    }
    */
}


//______________________________________________________________________________
 void MacroCell::Reset() {
    // reset data and get ready for next event
    // reset all front end chips and all pmts in this macrocell
    for(size_t iEC=0; iEC < fECs.size(); iEC++) {
        ElementaryCell *pEC = fECs[iEC];
        if ( pEC )
	    pEC->FrontEnd()->Reset();
    }
    for( size_t iPm=0; iPm < fPmts.size(); iPm++ ) {
        Photomultiplier* pPmt = fPmts[iPm];
        if ( pPmt )
            pPmt->Reset();
    }
}
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