Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

MacroCellData - source file

// class MacroCellData
// M. Pallavicini - created 20-11-2001
// Description of the data gathered by the MacroCell during the whole event
// 
#include <math.h>
#include "MacroCellData.hh"
#include "MacroCell.hh"
#include "FrontEndChip.hh"
#include "MacroCellHit.hh"
#include "EEvent.hh"
#include "Photomultiplier.hh"

ClassImp(MacroCellData)

//______________________________________________________________________________
 MacroCellData::MacroCellData( MacroCell* p ) : pCell(p) {
    // ctor

    fGtuStart = 999999;
    fGtuEnd = 0;
    fGtuTrigger = 999999;

    SetEmpty();
}

//______________________________________________________________________________
 MacroCellData::~MacroCellData() {
    // dtor
    
    
    map<Int_t, map<Int_t,ChipGtuData*>* >::const_iterator it3;
    for(it3=fChipData2.begin(); it3 != fChipData2.end(); it3++) {    
        map<Int_t,ChipGtuData*>* mm = it3->second;
        map<Int_t,ChipGtuData*>::const_iterator it4;
        for(it4=mm->begin(); it4!=mm->end(); it4++) {
            ChipGtuData* d=it4->second;
            if (d) delete d;
        }
        if ( mm ) {
            mm->clear();
            delete mm;
        }
    }
    fChipData2.clear();

    map<Int_t, vector<ChipGtuData*>* >::const_iterator it;
    for(it=fChipData.begin(); it != fChipData.end(); it++) {    
        vector<ChipGtuData*>* hits = it->second;
        if ( hits ) {
           /* for(size_t j=0; j < hits->size(); j++) {
	        ChipGtuData* d = (*hits)[j];
	        if (d)
	            delete d;
            }*/
            hits->clear();
            delete hits;
        }
    }
    fChipData.clear();
    
    map<Int_t, vector<MacroCellHit*>* >::const_iterator it2;
    for(it2=fData.begin(); it2 != fData.end(); it2++) {    
        vector<MacroCellHit*>* hits = it2->second;
        if ( hits ) {
            for(size_t j=0;j<hits->size(); j++) {
	        MacroCellHit* h = (*hits)[j];
	        if (h)
	            delete h;
            }
            hits->clear();
            delete hits;
        }
    }
    fData.clear();
}
 
//______________________________________________________________________________
 void MacroCellData::BuildGtu( Int_t gtu_num ) {
    // perform the single GTU analysis
    // look for X & Y logic for the whole macrocell
    // compute the number of hits and the time recorded for each pixels
    // including ghosts
    // data is saved into a map

    Int_t total_counts = 0;
    Double_t trigger_time = HUGE;

    fData[gtu_num] = new vector<MacroCellHit*>;

    Bool_t active = kFALSE;

    // get the list of ChipGtuData associated to this GTU
    vector<ChipGtuData*> *v = fChipData[gtu_num];
    if ( v == NULL ) {
        return;
    }

    // flags for ghost calculation
    vector<Int_t> ColumnFlags;
    vector<Int_t> RowFlags;
    ColumnFlags.clear();
    RowFlags.clear();

    // loop on all objects
    vector<ChipGtuData*>::const_iterator it = v->begin();
    for( ; it != v->end(); it++) {
        ChipGtuData *chdat = *it;
        if ( chdat ) {
            Int_t x;
            Int_t y;
            Double_t t;
            Int_t nch = chdat->FrontEnd()->Channels();
            if ( chdat->GetXYLogic(x,y,t) ) {
                active = kTRUE;
                total_counts += chdat->FastOrHits();  // counts after gate opened
                for(Int_t i=0; i<nch; i++) {
                    if ( chdat->CheckCounter(i) ) {
                        //FIXME ChkCntr is kTRUE also if counts == threshold
                        //FIXME Hitsa with counts == threshod are also saved 
                        Int_t mx, my;
                        chdat->FrontEnd()->GetPixelCellRowCol( i, mx, my );
                        if ( t < trigger_time ) {
                            trigger_time = t;     // time at which the logic fired
                        }
                        // add this hit to the list
                        ChannelUniqueId uid = chdat->FrontEnd()->UniqueChanId(i);
                        fData[gtu_num]->push_back(new MacroCellHit(mx,my,total_counts,gtu_num,uid));
                        ColumnFlags.push_back(my);
                        RowFlags.push_back(mx);
                    }
                }
            }
        }   
    }

    // if there was activity in this gtu, increment the counter
    if ( active ) {
        if ( gtu_num < GtuStart() ) fGtuStart = gtu_num;
        if ( gtu_num > GtuEnd() ) fGtuEnd = gtu_num;
        fNumActiveGtus ++;  
    }

    // add ghost hits
    for(UInt_t i=0; i<RowFlags.size(); i++) {
        Int_t mx = RowFlags[i];
        for(UInt_t j=0; j<ColumnFlags.size(); j++) {
            Int_t my = ColumnFlags[j];
            Int_t uid = Cell()->GetUniqueIdRowCol(mx,my);
            // add hit (avoid duplication with check i != j because the hit was already added before)
            if ( uid && i!=j ) {
                fData[gtu_num]->push_back(new MacroCellHit(mx,my,total_counts,gtu_num,uid));
            }
        }
    }

    // all "hits" (real and ghosts) have the same number of counts
    // the macrocell has just one counter and keep track of every X Y
    // logic fired during the GTU
    // I assume here that when more than one XY pair is active, the
    // macrocell will have no memory of the time in which they occurred
    // and will just associate the total number of hits to all combinations
    // of x and y
    for(UInt_t i=0; i<fData[gtu_num]->size(); i++) {
        // set number of counts to the same value for all Macrocellhits
        (*fData[gtu_num])[i]->SetHits( total_counts );

        // FIXME: debug code        
        /*cout << "Hit " << i << ":" 
          << (*fData[gtu_num])[i]->Row() << " " 
          << (*fData[gtu_num])[i]->Col() << " " 
          << (*fData[gtu_num])[i]->Gtu() << " " 
          << (*fData[gtu_num])[i]->Hits()<< " " 
          << (*fData[gtu_num])[i]->UniqueId()<< " " << endl;
         */
    }
}


//______________________________________________________________________________
 void MacroCellData::Add( Int_t gtu_num, ChipGtuData* pData) {
    // add data from a chip; just stored into a map
    // a second map is also filled for triggering purposes

    // fill first map only if pData->IsEmpty() is kFALSE, which
    // means at least one channel had at lest 5 hits
    if ( !pData->IsEmpty() ) {
        if ( !fChipData[gtu_num] )
            fChipData[gtu_num] = new vector<ChipGtuData*>;   
        fChipData[gtu_num]->push_back( pData );
    }

    // fill second map every time
    Int_t id = pData->FrontEnd()->Id();
    if ( !fChipData2[id] )
        fChipData2[id] = new map<Int_t,ChipGtuData*>;
    (*fChipData2[id])[gtu_num] = pData;


    SetEmpty( kFALSE );
}

//______________________________________________________________________________
 string& MacroCellData::Dump() {
    // 
    // dump macrocell data onto a string
    // 
    char line[500];
    sprintf(line,"MacroCell %dn",Cell()->Id());
    text_dump.append(line);
    sprintf(line,"Number of active GTUs = %dn",GtuEnd()-GtuStart());
    text_dump.append(line);
    for(UInt_t i=0; i < fData.size(); i++ ) {
        vector<MacroCellHit*>& v = *(fData[i]);
        if ( &v ) {
            sprintf(line,"GTU = %dn",i);
            text_dump.append(line);
            for( UInt_t j=0; j < v.size(); j++ ) {
                MacroCellHit *hit = v[j];
                if ( hit ) {
                    sprintf(line,"HIT %02d  X=%02d Y=%02d Hits=%02d n",
                            j,hit->Row(),hit->Col(), hit->Hits() );
                    text_dump.append(line);
                }
            }
        }
    }

    return text_dump;
}


//______________________________________________________________________________
 Bool_t MacroCellData::CheckContiguity(Int_t gtu1, Int_t gtu2 ) {
    // trigger function
    // returns kTRUE if gtu1 has at least one MacroCellHit
    // that is contiguous (in space) with one MacroCellHit of gtu2

    vector<MacroCellHit*>* hits1 = fData[gtu1];
    vector<MacroCellHit*>* hits2 = fData[gtu2];
    if ( !hits1 || !hits2 ) 
        return kFALSE;
    for(unsigned i1=0; i1 < hits1->size(); i1++) {
        MacroCellHit* hit1 = (*hits1)[i1];
        if ( hit1) {
            for(unsigned i2=0; i2 < hits2->size(); i2++) {
                MacroCellHit* hit2 = (*hits2)[i2];
                if ( hit2) {
                    if ( (*hit1)%(*hit2) ) {  // % operator for MacroCellHit
                        return kTRUE;
                    }
                }
            }
        }
    }
    return kFALSE;
}

//______________________________________________________________________________
 void MacroCellData::SimulateTrigger() {
    // simulate trigger using all engines associated to the macrocell

    // clear trigger word in all engines
    TriggerEngine::ResetTriggerWord();

    // get iterator over existing engines
    map<ETriggerTypeIdentifier,TriggerEngine*>::const_iterator it = Cell()->GetEngines().begin();

    // iterate and simulate trigger
    for( ; it != Cell()->GetEngines().end(); it++ ) {
        TriggerEngine *trg = it->second;
        trg->Simulate( this );
        if ( trg->HasTriggered() ) {
            SetGtuTrigger( trg->GetGtuTrigger() );
        }
    }
}

//______________________________________________________________________________
 Double_t MacroCellData::GtuTimeStart() {
    // time in ns of the first edge of the first GTU for this event
    // the time is measured from the Photons time
    
    Double_t start = Cell()->GetGtuBegin();
    start += GtuStart()*Cell()->GetGtuLength();
    return start;
}
    

//______________________________________________________________________________
 Double_t MacroCellData::GtuTimeEnd() {
    // same for second edge of last GTU
    
    Double_t end = Cell()->GetGtuBegin();
    end += (GtuEnd()+1.)*Cell()->GetGtuLength();
    return end;
}


//______________________________________________________________________________
 Int_t MacroCellData::NumMacroCellHits() {
    // compute the total number of hits and returns it

    Int_t NumHits = 0;
    for(Int_t iGtu = GtuStart(); iGtu < GtuEnd(); iGtu++) {
        if ( Hits(iGtu) ) {
            NumHits += Hits(iGtu)->size();
        }
    }
    return NumHits;
}

//______________________________________________________________________________
 ChipGtuData* MacroCellData::GetChipGtuData(Int_t chip, Int_t gtu) {
    // Return data of a specific chip in a given gtu
    
    if ( fChipData2.size()==0 ) return NULL;
    
    if ( fChipData2.count(chip)==0 ) return NULL;
    map<Int_t, ChipGtuData*> &m = *(fChipData2[chip]);
    if ( m.count(gtu) ) return m[gtu];
    else return NULL;
}
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