Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

ElecTestDetTransManager - source file

// ESAF : Euso Simulation and Analysis Framework
// $Id: ElecTestDetTransManager.cc,v 1.29 2005/11/02 13:31:12 pesce Exp $
// M. Pallavicini created May, 12 2003

#include "ElecTestDetTransManager.hh"
#include "Photon.hh"
#include "EusoDetector.hh"
#include "EusoElectronics.hh"
#include "MacroCell.hh"
#include "Photomultiplier.hh"
#include "EDetectorPhotonAdder.hh"
#include "PhotonsOnPupil.hh"
#include "ConfigFileParser.hh"
#include "Config.hh"
#include "TMath.h"

using namespace TMath;

ClassImp(ElecTestDetTransManager)

//______________________________________________________________________________
 ElecTestDetTransManager::ElecTestDetTransManager() {
    //
    // Constructor
    //

    // total number of photons generated
    fNumPhotons = (Int_t)Conf()->GetNum("ElecTestDetTransManager.fNumPhotons");
    
    // starting pixel 
    fMacroCellId = (Int_t)Conf()->GetNum("ElecTestDetTransManager.fMacrocellId");
    fPmtId = (Int_t)Conf()->GetNum("ElecTestDetTransManager.fPmtId");
    fChanId = (Int_t)Conf()->GetNum("ElecTestDetTransManager.fChanId");
    fUniqueChanId = (Int_t)Conf()->GetNum("ElecTestDetTransManager.fUniqueChanId");
    
    // start and end time
    fStartTime = Conf()->GetNum("ElecTestDetTransManager.fStartTime")*sou::ns;
    fEndTime = Conf()->GetNum("ElecTestDetTransManager.fEndTime")*sou::ns;

    if ( fStartTime > fEndTime )
        Msg(EsafMsg::Panic) << "In ElecTestDetTransManager must be EndTime > StartTime " << MsgDispatch;


    // if not zero, number of pixel
    // positive: row
    // negative: column
    fTrackLength = (Int_t)Conf()->GetNum("ElecTestDetTransManager.fTrackLength");

    // hole in the track
    fHole = Conf()->GetBool("ElecTestDetTransManager.fHole");
    fHolePosition = (Int_t)Conf()->GetNum("ElecTestDetTransManager.fHolePosition");

}

//______________________________________________________________________________
 ElecTestDetTransManager::~ElecTestDetTransManager() {
    //
    // Dtor
    //
}

//______________________________________________________________________________________
 void ElecTestDetTransManager::Go( PhotonsOnPupil* photons ) {
    //
    // fill electronics ignoring photons
    //
    
    if ( Conf()->GetStr("ElecTestDetTransManager.fMethod")=="uniformpixel" ||
         Conf()->GetStr("ElecTestDetTransManager.fMethod")=="randompixel") {
        PixelTest();
    } else if ( Conf()->GetStr("ElecTestDetTransManager.fMethod")=="track")  {
        Track();
    } else if ( Conf()->GetStr("ElecTestDetTransManager.fMethod")=="backstudy") {
        BackgroundStudy();
    }  else if ( Conf()->GetStr("ElecTestDetTransManager.fMethod")=="pmt")  {
        SinglePmt();
    } else {
        Msg(EsafMsg::Panic) << "Wrong value in fMethod" << MsgDispatch;
    }
}

//_______________________________________________________________________________________
 void ElecTestDetTransManager::Track() {
    //
    // Generate a test track on the focal surface
    //
    if ( fTrackLength == 0 )
        Msg(EsafMsg::Panic) << "You must specify a not null track length" << MsgDispatch;
    if ( fHole && (fHolePosition <=1 || fHolePosition >= TMath::Abs(fTrackLength)) )
        Msg(EsafMsg::Panic) << "In ElecTestDetTransManager fHolePosition is not valid." << MsgDispatch;

    MacroCell *cell = 0;
    Photomultiplier *pmt = 0;
    Int_t ch = 0;
    if ( fUniqueChanId > 0 ) {
        GetEusoDetector()->GetEusoElectronics()->ElectronicsMap(&cell,&pmt,ch,fUniqueChanId);
        fMacroCellId = cell->Id() + 1;
        fPmtId = pmt->Id() + 1;
        fChanId = ch + 1;
    } 
    else {
        cell = GetEusoDetector()->GetEusoElectronics()->Cell( fMacroCellId-1 );
        if ( cell ) {
            if ( fPmtId < ((Int_t)(cell->Pmts()->size())) ) {
                pmt = cell->GetPmt( fPmtId-1 );
            }
            else {
                MsgForm(EsafMsg::Panic, "Wrong pmt identifier: Macrocell %d has less than %d pmts", 
                        fMacroCellId, fPmtId);
            }
        }
        ch = fChanId-1;
    }

    // generate the required number of photons equally distributed in time
    // in the required time interval
    Double_t start = fStartTime;

    ConfigFileParser *pConfig = Config::Get()->GetCF("Electronics","MacroCell");
    Double_t gtu = pConfig->GetNum("MacroCell.fGtuTimeLength");

    Int_t chstep = 0;
    Int_t chint = 1;
    Int_t counter = 0;
    Int_t trackcounter = 0;
    if ( fTrackLength ) {
        if ( fTrackLength > 0 ) {
            chstep = 1;
            chint = fNumPhotons / fTrackLength;
            if ( fHole ) chint = fNumPhotons / (fTrackLength-1);
            counter = ch % pmt->Geometry()->Rows();
        } else {
            chstep = pmt->Geometry()->Rows();
            chint = - fNumPhotons / fTrackLength;
            if ( fHole ) chint = - fNumPhotons / (fTrackLength-1);
            counter = ch / pmt->Geometry()->Rows();
        }
    } else {
        Msg(EsafMsg::Panic) << "You must specify a not null track length" << MsgDispatch;
    }
    Double_t step = gtu/chint;

#ifdef DEBUG
    Msg(EsafMsg::Debug) << "Rows: " << cell->GetRows() << MsgDispatch;
    Msg(EsafMsg::Debug) << "Columns: " << cell->GetColumns() << MsgDispatch;
    Msg(EsafMsg::Debug) << "Chips: " << cell->Chips() << MsgDispatch;
    Msg(EsafMsg::Debug) << "Step: " << step << MsgDispatch;
    Msg(EsafMsg::Debug) << "ChStep: " << chstep << MsgDispatch;
    Msg(EsafMsg::Debug) << "ChInt: " << chint << MsgDispatch;
#endif /* DEBUG */

    for(Int_t i=0; i < Abs(fTrackLength)*chint; i++) {
        if ( fHole && trackcounter == (fHolePosition-1) ) {
            ch += chstep;
            start += gtu;
            counter++;
            trackcounter++;
            if ( trackcounter == Abs(fTrackLength) ) return;

        }
        if ( counter < (pmt->Geometry()->Rows()) ) {
            pmt->AddTest( start, ch );        // use a special add function of the PMT
            start += step;
            if ( (i % chint) == chint-1 ) {
                ch += chstep;
                counter++;
                trackcounter++;
                if ( trackcounter == Abs(fTrackLength) ) return;
            }
        }
        if ( counter >= (pmt->Geometry()->Rows()) ) {
            pair<Int_t, Int_t> rcEnd = cell->GetRowColUniqueId(pmt->GetUniqueId(ch-chstep)); 
            pair<Int_t, Int_t> rcN = cell->GetRowColUniqueId(pmt->GetUniqueId(ch-chstep*2)); 
            Int_t new_row = rcEnd.first; 
            Int_t new_col = rcEnd.second;
            Int_t step_row(0), step_col(0);
            if ((rcEnd.first-rcN.first)) step_row = Sign(1,(rcEnd.first-rcN.first));
            if ((rcEnd.second-rcN.second)) step_col = Sign(1,(rcEnd.second-rcN.second));

            Photomultiplier *pmt_new = 0;
            MacroCell *cell_new = 0;
            Int_t kk(0);
            while( (!pmt_new || pmt_new->Id()==pmt->Id()) && kk<12 ) {
                new_row += step_row;
                new_col += step_col;
                if ( new_row > (cell->GetRows()*pmt->Geometry()->Rows()) || new_row < 1 || 
                        new_col > (cell->GetColumns()*pmt->Geometry()->Rows()) || new_col < 1 ) {
                    Msg(EsafMsg::Debug) << "New row and/or column not valid. Stop" << MsgDispatch;
                    return;
                }
                if (cell->GetUniqueIdRowCol(new_row,new_col))
                    GetEusoDetector()->GetEusoElectronics()->ElectronicsMap(&cell_new, &pmt_new, ch, cell->GetUniqueIdRowCol(new_row,new_col));
                kk++;
            }
            if ( !cell_new || cell_new->Id() != cell->Id() ) {
                Msg(EsafMsg::Debug) << "Reached end of macrocell. Stop." << MsgDispatch;
                return;
            }
            //cout << new_row << " " << new_col << " numpmts " << cell->Pmts()->size() << endl;
            if (pmt_new && pmt_new->Id()!=pmt->Id()) {
                //cout << pmt->Id() << " " << pmt_new->Id() << endl;
                pmt = pmt_new;
                fChanId = ch + 1;
                counter = 0;
            } else {
                Msg(EsafMsg::Debug) << "Not found new pmt. Stop." << MsgDispatch;
                return;
            }
        }
    }
}

//____________________________________________________________________________________
 void ElecTestDetTransManager::SinglePmt() {
    //
    // track in a single PMT
    //
    if ( fTrackLength == 0 )
        Msg(EsafMsg::Panic) << "You must specify a not null track length" << MsgDispatch;
    if ( fHole && (fHolePosition <=1 || fHolePosition >= TMath::Abs(fTrackLength)) )
        Msg(EsafMsg::Panic) << "In ElecTestDetTransManager fHolePosition is not valid." << MsgDispatch;

    MacroCell *cell=0;
    Photomultiplier *pmt=0;
    Int_t ch;
    if ( fUniqueChanId > 0 ) {
        GetEusoDetector()->GetEusoElectronics()->ElectronicsMap(&cell,&pmt,ch,fUniqueChanId);
        fMacroCellId = cell->Id() + 1;
        fPmtId = pmt->Id() + 1;
        fChanId = ch + 1;
    } 
    else {
        cell = GetEusoDetector()->GetEusoElectronics()->Cell( fMacroCellId-1 );
        if ( cell ) {
            if ( fPmtId < ((Int_t)(cell->Pmts()->size())) ) {
                pmt = cell->GetPmt( fPmtId-1 );
            }
            else {
                MsgForm(EsafMsg::Panic, "ElecTestDetTransManager: Wrong pmt identifier: Macrocell %d has less than %d pmts", 
                      fMacroCellId, fPmtId);
            }
        }
        ch = fChanId-1;
    }
   
    //ConfigFileParser *pConfig = Config::Get()->GetCF("Electronics","MacroCell");
    //Double_t gtu = pConfig->GetNum("MacroCell.GtuTimeLength");

    // generate the required number of photons equally distributed in time
    // in the required time interval
    Double_t start = fStartTime;
    Double_t step = (fEndTime-fStartTime)/fNumPhotons;
    Int_t chstep = 0;
    Int_t chint = 1;
    if ( fTrackLength ) {
        if ( fTrackLength > 0 ) {
            chstep = 1;
            chint = fNumPhotons / fTrackLength;
        }
        else {
            chstep = pmt->Geometry()->Rows();
            chint = - fNumPhotons / fTrackLength;
        }
    }

    //Double_t step = gtu/chint; 
    Msg(EsafMsg::Debug) << "Step: " << step << MsgDispatch;
    Msg(EsafMsg::Debug) << "ChStep: " << chstep << MsgDispatch;
    Msg(EsafMsg::Debug) << "ChInt: " << chint << MsgDispatch;
    
    for(Int_t i=0; i < TMath::Abs(fTrackLength)*chint; i++) {
        pmt->AddTest( start, ch );        // use a special add function of the PMT
//        pmt->AddTest( start, ch+8 );        // use a special add function of the PMT
        start += step;
        if (( i % chint ) == (chint-1))
            ch += chstep;
    }

}

//____________________________________________________________________________
 void ElecTestDetTransManager::PixelTest() {
    //
    // Special method to test only a pixel
    //

    TRandom* rndm = EsafRandom::Get();
    Bool_t randomtime = kFALSE;
    if ( Conf()->GetStr("ElecTestDetTransManager.fMethod")=="randompixel" ) randomtime = kTRUE;
    MacroCell *cell=0;
    Photomultiplier *pmt=0;
    Int_t ch;
    if ( fUniqueChanId > 0 ) {
        GetEusoDetector()->GetEusoElectronics()->ElectronicsMap(&cell,&pmt,ch,fUniqueChanId);
        fMacroCellId = cell->Id() + 1;
        fPmtId = pmt->Id() + 1;
        fChanId = ch + 1;
    } 
    else {
        cell = GetEusoDetector()->GetEusoElectronics()->Cell( fMacroCellId-1 );
        if ( cell ) {
            if ( fPmtId < ((Int_t)(cell->Pmts()->size())) ) {
                pmt = cell->GetPmt( fPmtId-1 );
            } else {
                MsgForm(EsafMsg::Panic, "ElecTestDetTransManager: Wrong pmt identifier: Macrocell %d has less than %d pmts", 
                      fMacroCellId, fPmtId);
            }
        }
        ch = fChanId-1;
    }

    ConfigFileParser *pConfig = Config::Get()->GetCF("Electronics","MacroCell");
    Double_t gtu = pConfig->GetNum("MacroCell.fGtuTimeLength");

    Double_t start = fStartTime;
    Int_t numgtu = Nint(Ceil((fEndTime-fStartTime)/gtu));
    Int_t numphgtu = Nint(Ceil(fNumPhotons / numgtu));
    Double_t timestep = gtu/numphgtu;

    Msg(EsafMsg::Info) << "Num GTU: " << numgtu << MsgDispatch;
    Msg(EsafMsg::Info) << "Num ph per GTU: " << numphgtu << MsgDispatch;
    if ( !randomtime) {
        Msg(EsafMsg::Info) << "Time step: " << timestep << " ns" << MsgDispatch;
        Msg(EsafMsg::Info) << "Start time: " << start << " ns" << MsgDispatch;
        Msg(EsafMsg::Info) << "Stop time: " << start+(numphgtu-1)*timestep << " ns" << MsgDispatch;
    } else {
        Msg(EsafMsg::Info) << "Photons randomly distributed in the gtu." << MsgDispatch;
    }
    
    // add photons
    for(Int_t i(0); i<numgtu; i++) {
        for(Int_t j(0); j<numphgtu; j++ ) {

            if ( !randomtime ) {
                pmt->AddTest(start+j*timestep, ch);
            } else {
                pmt->AddTest(start+gtu*rndm->Rndm(),ch);

            }
            
        }
        start += gtu;
    }
}


//____________________________________________________________________________
 void ElecTestDetTransManager::BackgroundStudy() {
    //
    // method for studying background olnly. To be used with background enabled
    //
    ConfigFileParser *pElConfig = Config::Get()->GetCF("Electronics","EusoElectronics");
    if ( pElConfig->GetStr(string("EusoElectronics.fNightGlow")) == "none" )
        Msg(EsafMsg::Warning) << "You are studying background but background is not enabled in EusoElectronics.cfg" << MsgDispatch;

    MacroCell *cell=0;
    Photomultiplier *pmt=0;
    Int_t ch;
    if ( fUniqueChanId > 0 ) {
        GetEusoDetector()->GetEusoElectronics()->ElectronicsMap(&cell,&pmt,ch,fUniqueChanId);
        fMacroCellId = cell->Id() + 1;
        fPmtId = pmt->Id() + 1;
        fChanId = ch + 1;
    }    
    else {
        cell = GetEusoDetector()->GetEusoElectronics()->Cell( fMacroCellId-1 );
        if ( cell ) {
            if ( fPmtId < ((Int_t)(cell->Pmts()->size())) ) {
                pmt = cell->GetPmt( fPmtId-1 );
            }
            else {
                MsgForm(EsafMsg::Panic, "ElecTestDetTransManager: Wrong pmt identifier: Macrocell %d has less than %d pmts", 
                      fMacroCellId, fPmtId);
            }
        }
        ch = fChanId-1;
    }

    ConfigFileParser *pConfig = Config::Get()->GetCF("Electronics","MacroCell");
    Double_t gtu = pConfig->GetNum("MacroCell.fGtuTimeLength");

    Double_t start = fStartTime;
    //Double_t step = (fEndTime-fStartTime)/fNumPhotons;
    Int_t numgtu = (Int_t)((fEndTime-fStartTime)/gtu);
    Int_t numphgtu = (Int_t) (fNumPhotons / numgtu);

    for(Int_t i(0); i<numgtu; i++) {
        for(Int_t j(0); j<numphgtu; j++ ) {
            pmt->AddTest(start, ch);
        }
        start += gtu;
        fPmtId++;
        if ( fPmtId >= ((Int_t)(cell->Pmts()->size())) ) fPmtId = 1;
        pmt = cell->GetPmt( fPmtId-1 );
    }
}
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