Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

ListPhotonsInAtmosphere - source file

// ESAF : Euso Simulation and Analysis Framework
// $Id: ListPhotonsInAtmosphere.cc,v 1.20 2005/11/14 16:37:03 moreggia Exp $
// Anne Stutz created Dec,  1 2003

#include "ListPhotonsInAtmosphere.hh"
#include "SinglePhoton.hh"
#include "BunchOfPhotons.hh"
#include <stdexcept>

ClassImp(ListPhotonsInAtmosphere)

//______________________________________________________________________________
 ListPhotonsInAtmosphere::ListPhotonsInAtmosphere() : PhotonsInAtmosphere("list") {
    //
    // ctor
    //
    fNbNotSaved = 0;
    fCountS = 0;
    fCountB = 0;
    fTrackNbSteps = 0;
    fBeforeTrackstart = 0;
    fTrack.clear();
}

//______________________________________________________________________________
 ListPhotonsInAtmosphere::ListPhotonsInAtmosphere(const ListPhotonsInAtmosphere& o) : PhotonsInAtmosphere(o) {
    // 
    // cpy ctor
    // 
    Copy(o);
    fNbNotSaved = o.GetNbNotSaved();
    fCountS = 0;
    fCountB = 0;
}

//______________________________________________________________________________
 ListPhotonsInAtmosphere::~ListPhotonsInAtmosphere() {
    // 
    // dtor
    //
    Reset();
}

//______________________________________________________________________________
 SinglePhoton* ListPhotonsInAtmosphere::GetSingle() const {
    // 
    // Extract one photon from the list
    //
    if(fCountS == fListSingle.size()) {
	return 0;
    }
    return fListSingle[fCountS++];
}

//______________________________________________________________________________
 BunchOfPhotons* ListPhotonsInAtmosphere::GetBunch() const {
    // 
    // Extract one Bunch of photons from the list
    //
    if(fCountB == fListBunch.size()) {
       return 0;
    }
    return fListBunch[fCountB++];  
}

//______________________________________________________________________________
 void ListPhotonsInAtmosphere::Add(SinglePhoton* p, Bool_t saved) {
    // 
    // add photon to the lists
    // if saved true, means photon is already saved into root
    // 
    if(p) {
        if(p->Status() > 4) {
	    // photons dead during scattering simu are not saved, and destroyed here
	    SafeDelete(p);
	    return;
	}
        fListSingle.push_back(p);
	fNbNotSaved++;
    }
    else Msg(EsafMsg::Warning) <<"Trying to add NULL SinglePhoton in ListPhotonsInAtmosphere" << MsgDispatch;
}

//______________________________________________________________________________
 void ListPhotonsInAtmosphere::Add(BunchOfPhotons* p) {
    // 
    // Add bunch of photons to the lists
    //

    if(p) fListBunch.push_back(p);
    else Msg(EsafMsg::Warning) <<"Trying to add NULL BunchOfPhotons in ListPhotonsInAtmosphere" << MsgDispatch;
}

//______________________________________________________________________________
 void ListPhotonsInAtmosphere::Add(vector<SinglePhoton*>& list, Bool_t saved) {
    // 
    // Add a list of SinglePhoton to the list of singles
    // IMPORTANT : "list" is then destroyed to avoid wrong manipulation of pointers
    // if saved true, means SinglePhotons are already saved into root
    //
    for(size_t i=0; i<list.size(); i++) {
        if(list[i]->Status() > 4) {
	    // photons dead during scattering simu are not saved, and destroyed here
	    SafeDelete(list[i]);
	    continue;
	}
        fListSingle.push_back(list[i]);
	if(!saved) fNbNotSaved++;
    }
    list.clear();
}

//______________________________________________________________________________
 void ListPhotonsInAtmosphere::Add(ListPhotonsInAtmosphere& list, Bool_t saved) {
    // 
    // Add the elements of the given list
    // IMPORTANT : "list" is then destroyed to avoid wrong manipulation of pointers
    // if saved true, means SinglePhotons are already saved into root
    //
    for(size_t i=0; i<list.GetListOfBunch().size(); i++)
        fListBunch.push_back(list.GetListOfBunch()[i]);

    for(size_t i=0; i<list.GetListOfSingle().size(); i++) {
        fListSingle.push_back(list.GetListOfSingle()[i]);
	if(!saved) fNbNotSaved++;
    }
    list.Clear();
}

//______________________________________________________________________________
 void ListPhotonsInAtmosphere::Copy(const vector<SinglePhoton*>& list, Bool_t saved) {
    //
    // Same as the matching Add() method, BUT copies of pointers hold by list
    // are created, instead of storing the same pointers
    //
    SinglePhoton* s = 0;
    for(size_t i=0; i<list.size(); i++) {
        s = new SinglePhoton(*list[i]);
        fListSingle.push_back(s);
	if(!saved) fNbNotSaved++;
    }
}



//______________________________________________________________________________
 void ListPhotonsInAtmosphere::Copy(const ListPhotonsInAtmosphere& list, Bool_t saved) {
    //
    // Same as the matching Add() method, BUT copies of list's SinglePhoton and
    // BunchOfPhotons are created, instead of storing the pointers hold by
    // list, so that the internal vectors of list are not destroyed 
    //
    SinglePhoton* s = 0;
    BunchOfPhotons* b = 0;
    for(size_t i=0; i<list.GetListOfBunch().size(); i++) {
        b = new BunchOfPhotons(*(list.GetListOfBunch()[i]));
        fListBunch.push_back(b);
    }

    for(size_t i=0; i<list.GetListOfSingle().size(); i++) {
        s =  new SinglePhoton(*(list.GetListOfSingle()[i]));
        fListSingle.push_back(s);
	if(!saved) fNbNotSaved++;
    }
    
    if(list.GetNbTrackSteps()) {
        fTrack.reserve(list.GetNbTrackSteps());
	for(UInt_t i = 0; i<list.GetNbTrackSteps(); i++) fTrack[i] = list.GetTrackStep(i);
    }
    else ClearTrack();
}

//______________________________________________________________________________
 void ListPhotonsInAtmosphere::Clear() {
    // 
    // Clear the two lists
    //
    fListSingle.clear();
    fListBunch.clear();
    fNbNotSaved = 0;
    fCountS = 0;
    fCountB = 0;
    fBeforeTrackstart = 0;

}


//______________________________________________________________________________
 void ListPhotonsInAtmosphere::Reset(int t) {
    //
    // Delete photons in "vector" lists
    // - t = 0       both list, fTrack deleted
    // - t = 1       singles not deleted
    // - t = 2       bunches and fTrack not deleted
    //
    if(t < 0 || t > 2) Msg(EsafMsg::Warning) <<"<Reset> wrong t value, list not reset" << MsgDispatch;
    SinglePhoton* p = 0;
    if(t != 1) {
        for(size_t i=0; i<fListSingle.size(); i++) {
            p = fListSingle[i];
            SafeDelete(p);
        }
        fListSingle.clear();
        if(fNbNotSaved) cout<<"[Warning] <ListPhotonsInAtmosphere::Reset>  List contains not saved SinglePhotonsn";
	fNbNotSaved = 0;
        fCountS = 0;
    }

    BunchOfPhotons* bp = 0;
    if(t != 2) {
        for(size_t i=0; i<fListBunch.size(); i++) {
            if(!i) fListBunch[0]->Reset();   // to reset static data members
            bp = fListBunch[i];
            SafeDelete(bp);
        }
        fListBunch.clear();
        fCountB = 0;
	ClearTrack();
    }
}

//_____________________________________________________________________________
 UInt_t ListPhotonsInAtmosphere::TrackStepIndex(const EarthVector& pos) const {
    //
    // Return the fTrack step index that matches pos projection on the track
    //
    EarthVector first = fTrack[0];
    EarthVector last = fTrack[fTrackNbSteps-1];
    
    Double_t mag = (pos-first).Dot(last-first)/(last-first).Mag();
    if(mag < 0) {
	fBeforeTrackstart++;
        Msg(EsafMsg::Debug) <<"<TrackStepIndex> mag<0 = "<<mag<<" -> put to zero, ("<<fBeforeTrackstart<<" photons)" << MsgDispatch;
	mag = 0;
    }
    
    UInt_t nabove, nbelow, middle;
    nabove = fTrackNbSteps+1;
    nbelow = 0;
    while(nabove-nbelow > 1) {
       middle = (nabove+nbelow)/2;
       if (mag == (fTrack[middle-1]-first).Mag()) return middle-1;
       if (mag  < (fTrack[middle-1]-first).Mag()) nabove = middle;
       else nbelow = middle;
    }
    return nbelow-1;
}

//_____________________________________________________________________________
 UInt_t ListPhotonsInAtmosphere::TrackStepIndex(const EarthVector& pos, EarthVector& rtn) const {
    //
    // Same as above + returns pos projection along the track
    //
    EarthVector first = fTrack[0];
    EarthVector last = fTrack[fTrackNbSteps-1];
    Double_t mag = (pos-first).Dot(last-first)/(last-first).Mag();
    if(mag < 0) {
	fBeforeTrackstart++;
        Msg(EsafMsg::Debug) <<"<TrackStepIndex> mag<0 = "<<mag<<" -> put to zero, ("<<fBeforeTrackstart<<" photons)" << MsgDispatch;
	mag = 0;
    }
    rtn = (mag/(last-first).Mag()) * (last-first) + first;
    
    UInt_t nabove, nbelow, middle;
    nabove = fTrackNbSteps+1;
    nbelow = 0;
    while(nabove-nbelow > 1) {
       middle = (nabove+nbelow)/2;
       if (mag == (fTrack[middle-1]-first).Mag()) return middle-1;
       if (mag  < (fTrack[middle-1]-first).Mag()) nabove = middle;
       else nbelow = middle;
    }
    return nbelow-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