Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

ETriggerPainter - source file

// ESAF : Euso Simulation and Analysis Framework
// $Id: ETriggerPainter.cc,v 1.1 2005/02/18 15:16:46 pesce Exp $
// Author A.Thea Jun, 28 2004

/*****************************************************************************
 * ESAF: Euso Simulation and Analysis Framework                              *
 *                                                                           *
 *  Id: FocalSurfacePainter                                                  *
 *  Package: EventViewer                                                     *
 *  Coordinator: Alessandro.Thea                                             *
 *                                                                           *
 *****************************************************************************/

#include "ETriggerPainter.hh"
#include "EFocalSurfacePainter.hh"

#include "EDetector.hh"
#include "EElectronics.hh"
#include "EFee.hh"
#include "EAFee.hh"
#include "EMacroCellHit.hh"
#include "EChipTrackTrigger.hh"
#include "EChipTrackSegment.hh"

#include "Etypes.hh"
#include "ERunParameters.hh"

#include "Riostream.h"
#include "TCanvas.h"
#include "TList.h"
#include "TStyle.h"
#include "TVector3.h"


#include <TSystem.h>

//______________________________________________________________________________
//
//  ETriggerPainter
//
//  A painter to show the development of the signal on the focal surface.
//
//  Setters:
//  
//  ViewNspread
//  MaxColors
//
//
//  TO BE DONE
 
ClassImp(ETriggerPainter)
ClassImp(EPolygon)

//_____________________________________________________________________________
 ETriggerPainter::ETriggerPainter( EDetector* det, ERunParameters* runpars, EChipTrackTrigger* trg) {
    // 
    // Constructor
    //

    gStyle->SetPalette(1); //FIXME I would like a local palette
    fDetector = det;
    fRunPars =  runpars;
    fTrigger = trg;

    fLines = new TList;

    fGtu               = -1;

    // graphics options
    fViewNspread       = 5.;
    fViewThreshold     = 1;
    fViewBorder        = 0.2;

    fGifCanvasW        = 600;
    fGifCanvasH        = 600;

    fTxtCounter.SetTextAlign(33);
    fTxtCounter.SetTextSize(0.05);

    fPixelOff          = kFALSE;
    fPixelEmpty        = kFALSE;
    fGtuCounter        = kTRUE;
    fTimeIntegral      = kFALSE;

    fX1                = 0;
    fX2                = 0;
    fY1                = 0;
    fY2                = 0;

    fNumColors         = 50;
    fColorOffset       = 50;
    fMaxCounts         = 4;

    fPixelColorOff     = kBlack;
    fPixelColorEmpty   = kWhite;
    fPmtColorEmpty     = 49;
    fPmtColorHit       = 27;

    fPaveStatusBar.SetX1NDC(0.); 
    fPaveStatusBar.SetX2NDC(1.); 
    fPaveStatusBar.SetY1NDC(0.); 
    fPaveStatusBar.SetY2NDC(0.06); 
    fStatusBar   = kFALSE; 
    fPaveStatusBar.SetTextAlign(12);
    
    fCacheContents     = 0;

    fMaptoPaintID      = kTrgHits;

    if ( !fDetector || !fRunPars ) {
        Info("ETriggerPainter","Either Event or RunParameters is not defined. Painter made zombie.");
        MakeZombie(); 
        return;
    }

    if ( !fTrigger ) {
        Info("ETriggerPainter","Trigger is not defined. Painter made zombie.");
        MakeZombie(); 
        return;
    }
    
    LoadData();
    FindView( kAllSig );
    BuildPolyLines();

}

//_____________________________________________________________________________
 ETriggerPainter::~ETriggerPainter() {
    // 
    // Destructor
    // 
    
    Clear();
    SafeDelete(fLines);
}

//_____________________________________________________________________________
 void ETriggerPainter::Clear( Option_t *opt ) {
    //
    // Clear all temporay containers
    // 

    TString option(opt);

    if (option.Contains("C"))
        fLines->Delete("slow");
    else
        fLines->Clear();
     

    fPmtsToPaint.clear();
    fCache.clear();

    fPmtLines.clear();
    fPixelLines.clear();

    fChips.clear();
    fTrgChips.clear();
    fTrackHits.clear();
    fTrackSignals.clear();
    fTrgHits.clear();
    fTrgSignals.clear();
    fMacroCellHits.clear();
}

//_____________________________________________________________________________
 void ETriggerPainter::Draw( Option_t *opt ) {
    //
    // Build polylines and then append the FSP to pad
    //

    if ( IsZombie() ) return;
    
    TString options(opt);

    // rebuild the lines if needed FIXME
    if ( fPixelLines.empty() ) BuildPolyLines();

    AppendPad(opt);
}

//_____________________________________________________________________________
 void ETriggerPainter::Paint( Option_t *opt ) {

    TString options(opt);

    if (  (fGtu < fFirstGtu || fGtu > fLastGtu) && fGtu != -1 ) return;


    // calculate frame
    Float_t viewWidth = fViewNspread*fSpread.Mag();

    if ( viewWidth < fRunPars->GetPmtData().GetPadSide() ) return;
        
    Float_t padHeight = gPad->GetWh();
    Float_t padWidth  = gPad->GetWw();
    Float_t padMin = TMath::Min(padHeight, padWidth);

    Float_t xmin = -viewWidth*padWidth/padMin;
    Float_t ymin = -viewWidth*padHeight/padMin;
    Float_t xmax = viewWidth*padWidth/padMin;
    Float_t ymax = viewWidth*padHeight/padMin;

    Float_t expand = 1+fViewBorder;
    gPad->Range( expand*xmin, expand*ymin, expand*xmax, expand*ymax);

    // reset the box size
    fX1 = xmin;
    fX2 = xmax;
    fY1 = ymin;
    fY2 = ymax;
    
    FindPmtsToPaint( xmin, ymin, xmax, ymax);

    Counts_t mMapToPaint = GetMapToPaint();

    Int_t  nPmtPads = fRunPars->GetPmtData().GetNumPads();
    for(UInt_t i(0); i< fPmtsToPaint.size(); i++){

        // check if this pmt is empty
        Bool_t isEmpty = kTRUE;
        Int_t suid = fRunPars->GetPmtGeo( fPmtsToPaint[i] )->GetStartUniqueId();
        for( Int_t k(0); k < nPmtPads; k++) 
            isEmpty &= mMapToPaint.count(suid+k) == 0;

        // draw the pmt
        EPolygon *p = GetPmtLine( fPmtsToPaint[i] );
        p->SetFillColor( isEmpty ? fPmtColorEmpty : fPmtColorHit );
        p->Paint("f");
        p->Paint();

        // paint the pixels
        for( Int_t k(0); k < nPmtPads; k++) {
            Int_t uid = suid+k;
            Color_t c = -1;
            if ( mMapToPaint.count(uid) == 0  ) {
                if ( fPixelOff )
                    c = fPixelColorOff;
            } else if ( mMapToPaint[uid] == 0 ) {
                if ( fPixelEmpty )
                    c = fPixelColorEmpty;
            } else if ( mMapToPaint[uid] < fMaxCounts ) {
                c = fColorOffset+((Int_t)((Float_t)fNumColors/(Float_t)fMaxCounts)*mMapToPaint[uid]);
            } else {
                c = fColorOffset+fNumColors;
            }

            if ( c < 0 ) continue;
            p = GetPixelLine( uid );
            p->SetFillColor(c);

            p->Paint("f");
            p->Paint();
        }

    }

    if ( fGtuCounter ) {
        Float_t offset = 1.+fViewBorder/2.;
        if ( fGtu == -1 )
            fTxtCounter.SetText( xmax*offset, ymax*offset, "All Gtus");
        else
            fTxtCounter.SetText( xmax*offset, ymax*offset, Form("%d",fGtu));

        fTxtCounter.Paint();
    }
    
    if ( fStatusBar ) 
        fPaveStatusBar.Paint();

}

//______________________________________________________________________________
 Int_t ETriggerPainter::DistancetoPrimitive(Int_t px, Int_t py) {
    //
    //
    //
    Int_t pxl, pyl, pxt, pyt;
    Int_t px1 = gPad->XtoAbsPixel(fX1);
    Int_t py1 = gPad->YtoAbsPixel(fY1);
    Int_t px2 = gPad->XtoAbsPixel(fX2);
    Int_t py2 = gPad->YtoAbsPixel(fY2);
    if (px1 < px2) {pxl = px1; pxt = px2;}
    else           {pxl = px2; pxt = px1;}
    if (py1 < py2) {pyl = py1; pyt = py2;}
    else           {pyl = py2; pyt = py1;}

    if ( (px >= pxl && px <= pxt) && (py >= pyl && py <= pyt) ) return 0;
    else return 9999;

}

//______________________________________________________________________________
 void ETriggerPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py) {
    //
    // Execute an event when the mouse moves in the display active region
    //

    switch (event) {
        case kMouseMotion:
        //        case kButton1Up:
        if ( fStatusBar ) {
            Int_t pmtId=-1;
            Int_t pxUID=-1;
            
            size_t j;
            for (j=0; j<fPmtsToPaint.size(); j++) {
                if ( GetPmtLine(fPmtsToPaint[j])->DistancetoPrimitive(px,py) == 0 ) {
                    pmtId = fPmtsToPaint[j];
                    break;
                }
            }
            
            if ( pmtId == -1 ) return;

            Int_t  nPmtPads = fRunPars->GetPmtData().GetNumPads();
            // take the first uid in the mapmt
            Int_t suid = fRunPars->GetPmtGeo( pmtId )->GetStartUniqueId();
            for( Int_t k(0); k < nPmtPads; k++) {
                Int_t uid = suid+k;

                if ( fPixelLines.count(uid) == 0 ) break;

                if ( fPixelLines[uid]->DistancetoPrimitive(px,py) == 0 ) {
                    pxUID = uid;
                    break;
                }

            }
            
            Int_t chip = fRunPars->GetPmtGeo( pmtId )->GetFee();
            Int_t cell = fRunPars->GetPmtGeo( pmtId )->GetMC();
                        
            if ( pxUID != -1 ) {
                Counts_t mMap = GetMapToPaint();
                SetStatus(pxUID, pmtId, chip, cell, mMap[pxUID]);
            } else {
                SetStatus(-1);
            }

            gPad->Modified();
            gPad->Update();
            
            return;
            }            
            break;
        default:
            break;
    }

}

//______________________________________________________________________________
 char* ETriggerPainter::GetObjectInfo(Int_t px, Int_t py) const {
    //   
    //   Redefines TObject::GetObjectInfo.
    //
    if (!gPad) return (char*)"";
    static char info[64];
    Double_t x  = gPad->PadtoX(gPad->AbsPixeltoX(px))-fCenter.X();
    Double_t y  = gPad->PadtoY(gPad->AbsPixeltoY(py))-fCenter.Y();
    Int_t pmtId=-1;
    Int_t pxUID=-1;

    size_t j;
    for (j=0; j<fPmtsToPaint.size(); j++) {
        if ( FindPmtLine(fPmtsToPaint[j])->DistancetoPrimitive(px,py) == 0 ) {
            pmtId = fPmtsToPaint[j];
            break;
        }
    }

    if ( pmtId == -1 ) {
        sprintf(info,"(x=%g, y=%g, no pixel)",x,y);
    } else {
        Int_t  nPmtPads = fRunPars->GetPmtData().GetNumPads();
        // take the first uid in the mapmt
        Int_t suid = fRunPars->GetPmtGeo( pmtId )->GetStartUniqueId();
        for( Int_t k(0); k < nPmtPads; k++) {
            Int_t uid = suid+k;

            if ( fPixelLines.count(uid) == 0 ) break;

            map<Int_t, EPolygon* >::const_iterator it = fPixelLines.find(uid);
            if ( it->second->DistancetoPrimitive(px,py) == 0 ) {
                pxUID = uid;
                break;
            }

        }
        
        Int_t chip = fRunPars->GetPmtGeo( pmtId )->GetFee();
        Int_t cell = fRunPars->GetPmtGeo( pmtId )->GetMC();
        
        if ( pxUID != -1 ) {
            Counts_t mMap = GetMapToPaint();
            sprintf(info,"(x=%g, y=%g, cell id=%d, chip id=%d, pmt id=%d, px id=%d, counts=%d)",x,y,cell,chip,pmtId,pxUID,mMap[pxUID]);
        } else {
            sprintf(info,"(x=%g, y=%g, cell id=%d, chip id=%d, pmt id=%d, no pixel)",x,y,cell,chip,pmtId);
        }
    }

    return info;
}

//_____________________________________________________________________________
 void ETriggerPainter::FindView( ETrigId id ) {
    //
    // calculates center, spread and orientation of the viewport
    //

    if ( IsZombie() ) return;

    // define range
    Int_t totEntries(0);
    TVector3 vSum2(0.,0.,0.);
    fCenter.SetXYZ(0.,0.,0.);

    Int_t nCountsOverThres(0);

    GtuCounts_t& mViewMap = fTrackSignals;

    // find view center and axis
    GtuCounts_t::iterator
    Counts_t::iterator

    for(itGtu = mViewMap.begin(); itGtu !=  mViewMap.end(); itGtu++)
        for( itUId = (itGtu->second).begin(); itUId != (itGtu->second.end()); itUId++){
            if ( itUId->second == 0 ) continue;

            totEntries += itUId->second;

            if ( itUId->second < fViewThreshold ) continue;

            const EPmtGeo* pmt = fRunPars->GetPmtGeoByUId(itUId->first);
            
            // Pmt normals are downward oriented, while Z axis must be upward oreinted
            fZaxis -= pmt->GetNorm(); 

            TVector3 dummy = fRunPars->PixelCenter(itUId->first);
            fCenter += dummy*itUId->second;

            nCountsOverThres+= itUId->second;

        }
    
    Info("FindView","%d pixels to draw, %d over threshold", totEntries, nCountsOverThres);
    if ( !nCountsOverThres ) {
        Warning("FindView","Not possible to find the center. Try to Lower the threshold");


        const EPmtGeo* pmt = fRunPars->GetPmtGeoByUId(1);
        fCenter = pmt->GetCenter();
        fZaxis = pmt->GetNorm();
        fYaxis.SetXYZ(0,1,0);
        fXaxis = fYaxis.Cross(fZaxis).Unit();
        fYaxis = fZaxis.Cross(fXaxis).Unit();

    } else {
        fZaxis.SetMag(1.);

        // Y is fixed
        fYaxis.SetXYZ(0,1,0);
        fCenter *= 1./(Float_t)nCountsOverThres;


        // fix the axis
        fXaxis = fYaxis.Cross(fZaxis).Unit();
        fYaxis = fZaxis.Cross(fXaxis).Unit();
        // calculate spread along the axis
        for(itGtu = mViewMap.begin(); itGtu !=  mViewMap.end(); itGtu++)
            for( itUId = (itGtu->second).begin(); itUId != (itGtu->second.end()); itUId++){
                if ( itUId->second == 0 ) continue;

                if ( itUId->second < fViewThreshold ) continue;

                TVector3 dummy = fRunPars->PixelCenter(itUId->first)-fCenter;
                fSpread[0] += TMath::Power((dummy*fXaxis),2)*itUId->second;
                fSpread[1] += TMath::Power((dummy*fYaxis),2)*itUId->second;
                fSpread[2] += TMath::Power((dummy*fZaxis),2)*itUId->second;

            }

    }

    for(Int_t i(0); i<3; i++) {
        fSpread[i] = TMath::Sqrt(fSpread[i]/(Float_t)nCountsOverThres);
        fSpread[i] = TMath::Max(fSpread[i],(Double_t)fRunPars->GetPmtData().GetPadSide());
    }

}


//______________________________________________________________________________
 void ETriggerPainter::SetStatus(Int_t uid, Int_t pmt, Int_t chip, Int_t cell, Int_t counts) {
    //
    //
    //

    TText* txt = fPaveStatusBar.GetLine(0);
    if ( !txt )
       txt = fPaveStatusBar.AddText(""); 

    
    if ( uid == -1 ) {
        txt->SetText(txt->GetX(), txt->GetY(), "");
        return;
    }
    
    txt->SetText(txt->GetX(),
                 txt->GetY(),
                 Form("Cell %d  Chip %d     Pmt %d   Pixel %d   Counts %d",cell,chip,pmt, uid, counts));
    
}

//_____________________________________________________________________________
 void ETriggerPainter::BuildPolyLines() {
    // 
    // Creates all the polylines for all the hits in the event
    //
    
    if ( !fDetector ) {
        Error("BuildPolyLines","No Event defined");
        return;
    }

    // parse all maps and build all the pixels and the pmts
    GtuCounts_t::iterator
    Counts_t::iterator


    for(itGtu = fTrackHits.begin(); itGtu !=  fTrackHits.end(); itGtu++)
        for( itUId = itGtu->second.begin(); itUId != itGtu->second.end(); itUId++) {

            Int_t uid = itUId->first;
            GetPixelLine( uid );

            // associated pmt
            Int_t id = fRunPars->Pmt(uid);
            GetPmtLine( id );

        }

}

//_____________________________________________________________________________
 void ETriggerPainter::LoadData() {
    // 
    // Load data and fills GtuCounts from the event and the runparameters
    //

    Clear();

    fFirstGtu = kMaxInt;
    fLastGtu = -kMaxInt;

    // read EChipTrackSegment from trigger and fill map of "chip track hits" (all and only triggered)
    for(Int_t i(0); i<fTrigger->GetNumTracks(); i++) {
        EChipTrackSegment *track = fTrigger->GetTrack(i);
        Int_t chip_id = track->GetChipUid();
        for(Int_t j=track->GetGtuStart(); j<=track->GetGtuEnd(); j++ ) {
            if ( fChips[j].count(chip_id) == 0 )
                fChips[j][chip_id] = 1;
            else
                fChips[j][chip_id]++;
            if ( track->GetTriggered() ) {
                if ( fTrgChips[j].count(chip_id) == 0 )
                    fTrgChips[j][chip_id] = 1;
                else
                    fTrgChips[j][chip_id]++;
            }
            // look for first and last gtu
            if ( j < fFirstGtu ) fFirstGtu = j;
            if ( j > fLastGtu )  fLastGtu = j;
        }
    }

    // read EFee from event
    for(Int_t i(0); i<fDetector->GetNumFee(); i++) {
        EFee *dfee = fDetector->GetFee(i);
        Int_t uid =  dfee->GetChUId();
        Int_t gtu =  dfee->GetGtu();
        Int_t chip_id = fRunPars->FrontEndChip(uid);
                
        if ( fChips[gtu].count( chip_id ) != 0 ) {
            if ( fTrackHits[gtu].count( uid ) == 0 ) 
                fTrackHits[gtu][uid] = dfee->GetNumHits();
            else
                fTrackHits[gtu][uid] += dfee->GetNumHits();
        if ( fTrackSignals[gtu].count( uid ) == 0 ) 
                fTrackSignals[gtu][uid] = dfee->GetNumSignals();
            else
                fTrackSignals[gtu][uid] += dfee->GetNumSignals();
        }

        if ( fTrgChips[gtu].count( chip_id ) !=0 ) {
            if ( fTrgHits.count( uid ) == 0 ) 
                fTrgHits[gtu][uid] = dfee->GetNumHits();
            else
                fTrgHits[gtu][uid] += dfee->GetNumHits();
            if ( fTrgSignals.count( uid ) == 0 ) 
                fTrgSignals[gtu][uid] = dfee->GetNumSignals();
            else
                fTrgSignals[gtu][uid] += dfee->GetNumSignals();
        }

        // look for first and last gtu
        if ( gtu < fFirstGtu ) fFirstGtu = gtu;
        if ( gtu > fLastGtu )  fLastGtu = gtu;
    }

    // read CellHits from event
    for(Int_t i(0); i<fDetector->GetNumCellHits(); i++) {
        EMacroCellHit* mchit = fDetector->GetMacroCellHit(i);
        Int_t uid =  mchit->GetChUId();
        Int_t gtu =  mchit->GetGtu();

        if ( fMacroCellHits[gtu].count( uid ) == 0 ) 
            fMacroCellHits[gtu][uid] = mchit->GetCounts();
        else
            fMacroCellHits[gtu][uid] += mchit->GetCounts();

        // look for first and last gtu
        if ( gtu < fFirstGtu ) fFirstGtu = gtu;
        if ( gtu > fLastGtu )  fLastGtu = gtu;
    }

}


//_____________________________________________________________________________
 EPolygon* ETriggerPainter::GetPixelLine( Int_t uid ) {
    // 
    // Returns a EPolygon corresponding to uid if doesn't exist.
    // If doesn't exists yet in fPixelLines creates a new one. 
    //

    if ( fPixelLines.count(uid) != 0 )
        return fPixelLines[uid];
    
    // projections of the axis of the geometry

    Float_t x[5], y[5];
    for(Int_t iCorner(0); iCorner<4; iCorner++){
        TVector3 dummy = fRunPars->PixelCorner(uid,iCorner)-fCenter;
        x[iCorner] = dummy*fXaxis;
        y[iCorner] = dummy*fYaxis;
    }
    x[4] = x[0];
    y[4] = y[0];

    EPolygon *p = new EPolygon(5,x,y); 
    fPixelLines[uid] = p;
    fLines->Add(p);


    
    fPixelLines[uid] = p;
    fLines->Add(p);

    return p;
}

//_____________________________________________________________________________
 EPolygon* ETriggerPainter::FindPmtLine( Int_t id ) const {
    //
    // Lookf for EPolygon corresponding to id among the ones already created
    //
    EPolygon *pol = 0;
    
    if ( fPmtLines.count( id ) != 0 ) pol = fPmtLines.find(id)->second;
    return pol;
    
}

//_____________________________________________________________________________
 EPolygon* ETriggerPainter::GetPmtLine( Int_t id ) {
    //
    // Returns a EPolygon corresponding to id if doesn't exist.
    // If doesn't exists yet in fPmtLines creates a new one. 
    //

    if ( fPmtLines.count( id ) != 0 )
        return fPmtLines[id];

    // this pmt doesn't exists. make new polyline

    Float_t x[5], y[5];
    for(Int_t iCorner(0); iCorner<4; iCorner++){
        TVector3 dummy = fRunPars->PmtCorner(id, iCorner)-fCenter;
        x[iCorner] = dummy*fXaxis;
        y[iCorner] = dummy*fYaxis;
    }
    x[4] = x[0];
    y[4] = y[0];

    EPolygon *p = new EPolygon(5,x,y); 
    fPmtLines[id] = p;
    
    fLines->Add(p);
    return p;
}

//_____________________________________________________________________________
 void ETriggerPainter::FindPmtsToPaint( Float_t xmin, Float_t ymin, Float_t xmax, Float_t ymax ) {
    // 
    // Looks for Pmts which centers are in the viewport. 
    // Fills fPmtsToPaint and fPixelsToPaint
    //
    
    fPmtsToPaint.clear();

    for( Int_t i(1); i <= fRunPars->GetNumPmts(); i++) {
        TVector3 dummy = fRunPars->GetPmtGeo(i)->GetCenter()-fCenter;
        if ( dummy*fXaxis < xmin || dummy*fXaxis > xmax ||
             dummy*fYaxis < ymin || dummy*fYaxis > ymax )
            continue;

        // add the polyline to the list
        GetPmtLine(i);
        fPmtsToPaint.push_back(i);
    }

}


//_____________________________________________________________________________
 void ETriggerPainter::Play( Option_t *opt ) {
    // 
    // Start the movie
    //

    if ( gPad ) gPad->Clear();

    TString option(opt);

    Draw( option );

    fTimer->Connect("Timeout()","ETriggerPainter", this, "Animate()" );
    Rewind(); 

    Info("Play","Animation started");
    fTimer->TurnOn();
}

//_____________________________________________________________________________
 void ETriggerPainter::Animate() {
    //
    // Move to next animation step and increase the counter
    //
   
    if ( IsEnded() ) {
        // leave the last frame to be painted
        fGtu = fLastGtu;
        Stop();
        return;
    } 

    NextFrame();

    if ( gPad ) {
        gPad->Modified();
        gPad->Update();
    }

}

//_____________________________________________________________________________
 void ETriggerPainter::NextFrame() {
    //
    // Move the internal counter to the next frame
    //
    
    fGtu++;
}

//_____________________________________________________________________________
 void ETriggerPainter::MakeGifSequence(const char *option, const char *path) {
    //
    // Build a sequence of gifs inside a dedicated canvas.
    // Gifs are created with opt options 
    //


    TString opt(option);

    TCanvas *display = new TCanvas("MakeGifDisplay","MakeGifDisplay",
                                   fGifCanvasW, fGifCanvasH);

    fGtu = -1;

    display->GetListOfPrimitives()->Add(this,opt);
    display->Modified(kTRUE);

    display->SaveAs("AnimHead.gif");

    for( fGtu = fFirstGtu; fGtu <= fLastGtu; fGtu++) {
        display->Modified();
        display->Update();
        display->SaveAs(Form("%s%.3d.gif",path,fGtu));
    }

    fGtu = -1;
    display->Modified();
    display->SaveAs("AnimTail.gif");

    delete display;

}
//_____________________________________________________________________________
 Counts_t ETriggerPainter::GetMapToPaint() const {

    Counts_t mMapToPaint;

    const GtuCounts_t *pMap = GtuCountsToPaint();
    if (!pMap) return mMapToPaint;

    if (fGtu == -1 ) {
        // paint all hits superimposed

        GtuCounts_t::const_iterator
        for( itGtu = pMap->begin(); itGtu != pMap->end(); itGtu++)
            mMapToPaint += (itGtu->second);

    } else if ( fTimeIntegral ) {
        // draw superposition of all hits from first gtu to the current one.

        GtuCounts_t::const_iterator

        // check cache content
        if ( fCacheContents != fMaptoPaintID ) CacheTimeInt();

        // look for the right entry
        if ( (itGtu = fCache.find(fGtu)) != fCache.end() ) {
            mMapToPaint = (itGtu->second);
        } else {
            for( Int_t gtu = fFirstGtu; gtu <= fGtu; gtu++) {
                if ( (itGtu = pMap->find( gtu )) == pMap->end() ) continue;

                mMapToPaint += (itGtu->second);
            }
        }

    } else {
        // draw just a gtu
        mMapToPaint = pMap->find(fGtu)->second;

    }

    return mMapToPaint;

}

//_____________________________________________________________________________
 const GtuCounts_t* ETriggerPainter::GtuCountsToPaint() const {
   
    switch( fMaptoPaintID ) {
        case kAllHits:
            return &fTrackHits;
        case kAllSig:
            return &fTrackSignals;
        case kTrgHits:
            return &fTrgHits;
        case kTrgSig:
            return &fTrgSignals;
        case kCHits:
            return &fMacroCellHits;
        default:
            Error("MapToPaint","bad id in fMaptoPaintID, returning 0");
    }
     return 0;
}

//_____________________________________________________________________________
 void ETriggerPainter::CacheTimeInt() const {
    // cache data to speedup animation
    
    Info("CacheTimeInt","Caching data");
    
    Counts_t dummy;
    const GtuCounts_t *map = GtuCountsToPaint();
    if ( !map ) return;

    fCache.clear();

    GtuCounts_t::const_iterator
    for( Int_t gtu = fFirstGtu; gtu <= fLastGtu; gtu++ ) {
        if ( (itGtu = map->find(gtu)) != map->end())
        dummy += (itGtu->second); 
        fCache[gtu] = dummy;
    }

    fCacheContents = fMaptoPaintID;
    
}

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