source: JEM-EUSO/esaf_lal/tags/v1_r0/esaf/packages/simulation/detector/electronics/src/R11265U200Photomultiplier.cc @ 117

Last change on this file since 117 was 117, checked in by moretto, 11 years ago

ESAF version compilable on mac OS

File size: 8.7 KB
Line 
1/*****************************************************************************
2 * ESAF: Euso Simulation and Analysis Framework                              *
3 *                                                                           *
4 *  Id: R11265U200Photomultiplier                                               *
5 *  Package: Electronics                                                     *
6 *  Coordinator: Marco.Pallavicini                                           *
7 *                                                                           *
8 *****************************************************************************/
9
10//_____________________________________________________________________________
11//
12//   R11265U-100 high collection efficiency photomultiplier tube
13//   ===========================================================
14// 
15//   Class created by Camille Moretto & Sylvie Dagoret-Campagne @ LAL
16//   ================================================================
17//   and based on a copy of the R8900M64Photomultiplier class
18//   ========================================================
19//
20//   fgUsePmtAdd [string]: if yes Add() method calls Photomultiplier::Add() and
21//   uses average values for all pixels.
22//
23
24#include "R11265U200Photomultiplier.hh"
25#include "EusoElectronics.hh"
26#include "EusoDetector.hh"
27#include "EsafRandom.hh"
28#include "EConst.hh"
29#include "EDetectorPhotonAdder.hh"
30#include "NumbersFileParser.hh"
31#include "Photon.hh"
32
33using namespace sou;
34
35ClassImp(R11265U200Photomultiplier)
36
37R11265U200Photomultiplier::EStatus R11265U200Photomultiplier::fgStatus = kUndefined;
38
39vector<Double_t> R11265U200Photomultiplier::fgColEff;
40Interpolate* R11265U200Photomultiplier::fgQuantumEff           = NULL;
41Interpolate* R11265U200Photomultiplier::fgAngularDependence    = NULL;
42vector<Double_t>* R11265U200Photomultiplier::fgCrossTalkTable = NULL;
43
44//______________________________________________________________________________
45R11265U200Photomultiplier::R11265U200Photomultiplier( Int_t id, PmtGeometry* g ) :
46    Photomultiplier(id, g ) {
47    //
48    // Constructor
49    //
50    // initialize static data members
51    if ( fgStatus == kUndefined )  {
52
53        if ( Conf()->GetBool("R11265U200Photomultiplier.fgUsePmtAdd") )
54            fgStatus = kPmtAdd;
55        else {
56            fgStatus = kR8900Add;
57
58            //--------------------  begin  Satoi & Mario 's changes  -----------------
59
60            string cfgdir = Conf()->GetCfgDir()+"/"+Conf()->GetType()+"/"+Conf()->GetName()+"/";
61
62            // load Collection Efficiency from file
63            string s = cfgdir + Conf()->GetStr("R11265U200Photomultiplier.fCollectionEfficiency.FileName");
64            NumbersFileParser pce(s,4);
65            vector<Double_t> dummy=pce.GetCol(3);
66
67            if(dummy.size()==0)
68                Msg(EsafMsg::Panic) << "R11265U200Photomultiplier: "+s+"is empty!" << MsgDispatch;
69
70            for(size_t i(0);i<dummy.size();i++)
71                fgColEff.push_back(dummy[i]);
72            Msg(EsafMsg::Debug) << fgColEff.size() << " C.E. data loading..." << MsgDispatch;
73
74            // load Quantum Efficiency from file
75            fgQuantumEff = new Interpolate(cfgdir+Conf()->GetStr("R11265U200Photomultiplier.fQuantumEfficiency.FileName"));
76            fgQuantumEff->SetXUnit(nm);
77            Msg(EsafMsg::Debug) << "Quantum Efficiency data loading..." << MsgDispatch;
78
79            // load Angular Dependence from file
80            fgAngularDependence = new Interpolate(cfgdir+Conf()->GetStr("R11265U200Photomultiplier.fAngularDependence.FileName"));
81            fgAngularDependence->SetXUnit(deg);
82            Msg(EsafMsg::Debug) << "Angular Dependece data loading..." << MsgDispatch;
83
84            // load Cross Talk form file
85            // Cross Talk File Format:
86            // (ch.),x,y,(data1),(data2),...(data64)[CR] for each line
87            fgCrossTalkTable= new vector<Double_t>[64];
88            s = cfgdir + Conf()->GetStr("R11265U200Photomultiplier.fCrossTalk.FileName");
89            NumbersFileParser *dummy2 = new NumbersFileParser(s,67);
90            for(size_t j(0);j<64;j++){
91                // Get row No."j"
92                vector<Double_t> dummy2_line=dummy2->GetRow(j);
93                // Get data from colum No.3 to No.67
94                for(size_t k(3);k<dummy2_line.size();k++){
95                    // Load fgCrossTalkTable
96                    fgCrossTalkTable[j].push_back(dummy2_line[k]);
97                }
98            }
99
100            Msg(EsafMsg::Debug) << "Cross Talk data loading..." << MsgDispatch;
101        }
102    }
103    //--------------------  end  Satoi & Mario 's changes  -----------------
104
105}
106
107//______________________________________________________________________________
108R11265U200Photomultiplier::~R11265U200Photomultiplier() {
109    // Destructor
110}
111
112
113//______________________________________________________________________________
114Bool_t R11265U200Photomultiplier::Add(Photon& ph) {
115    //
116    // add a photon hit to be simulated
117    //
118    // use Photomultiplier::Add, temporary disabled
119    if ( fgStatus == kPmtAdd )
120        return Photomultiplier::Add(ph);
121
122    // new features after this line
123
124    // check if this photon hits this pmt
125    if (!Geometry()->IsInside( ph )) {
126        TVector3 r = (ph.pos-Geometry()->Position()) ;
127        Double_t x = r.Dot(Geometry()->GetX());
128        Double_t y = r.Dot(Geometry()->GetY());
129        Double_t z = r.Dot(Geometry()->GetZ());
130        MsgForm(EsafMsg::Warning, "Wrong ph. DIFF=(%.3e, %.3e, %.3e)  PROJ=(%.3e, %.3e, %.3e)",
131                r[0], r[1], r[2], x, y, z);
132        return kFALSE;
133    }
134
135    // get the channel number
136    Int_t ch = Geometry()->Pad(ph);
137
138    // negative if Photon is lost for geometrical reasons (dead spaces)
139    if ( ch < 0 )
140        return kFALSE;
141
142    // saving pixel id on the photon
143    ph.pixelUid = GetUniqueId(ch);
144
145    // if required, do association mapping between original
146    // theta phi in field of view and this channel
147    //FIXME: EusoMapping::Get()->Associate(this,ch,ph);
148
149    // if signal simulation is disabled, stop here
150    // if ( !(GetEusoDetector()->GetEusoElectronics()->GetSimulationStatus()) ) return kTRUE;
151    if ( !(GetEusoElectronics()->GetSimulationStatus()) ) return kTRUE;
152
153    TRandom* rndm = EsafRandom::Get();
154
155    //--------------------  beginning  Satoi & Mario 's changes  -----------------
156    // fgQuantum is not the same as our fgQuantumEff.
157    // fgQuantum    : constant.
158    // fgQuantumEff : depend on wavelength
159
160    // fgColEff depend on ch (pixel number).
161    // QuantumEff depend on wavelength of photon.
162    // AngularDependence depend on Theta of photon got by Detector.
163
164    // Computing D.E.
165    double ph_dir_theta = ph.dir.Theta();
166    if (fGeometry){
167        // calculate direction angle in relation with the geometry direction
168        ph_dir_theta = (ph.dir.Angle(-fGeometry->Normal()));
169    }
170    else {
171        Msg(EsafMsg::Panic) << "Geometry not defined." << MsgDispatch;
172    }
173    Double_t DetEff=fgColEff[ch]*fgQuantumEff->GetValue(ph.wl)*fgAngularDependence->GetValue(ph_dir_theta);
174
175    // Shot for D.E.
176    Double_t shot=rndm->Rndm(); // [0,1]
177    // Check if photon generate electron or not
178    if(shot > DetEff)
179            return kFALSE;  // photon is lost
180
181    // Shot2 for CrossTalk
182    Double_t shot2=rndm->Rndm(); // [0,1]
183
184    // Cross Talk
185    //  Get Cross Talk Data
186    vector<Double_t> *ChCrossTalk = &fgCrossTalkTable[ch];
187
188    // apply CrossTalk Technique
189    if (shot2 <= (*ChCrossTalk)[0] ) {
190        ch=0;
191    } else {
192        for(size_t kch(1); kch < ChCrossTalk->size(); kch++){
193            if( (shot2 >= (*ChCrossTalk)[kch-1] ) && ( shot2 <= (*ChCrossTalk)[kch] ) ){
194                ch=kch;
195                break;
196            }
197        }
198    }
199
200    // end of judge
201    // Msg(EsafMsg::Debug) << "photon hit pixel no. " << ch <<  MsgDispatch;
202
203    //-------------------------------- end Satoi & Mario 's changes --------------
204
205    // compute charge
206    Double_t delta = fgGainSigma * rndm->Gaus();
207    Double_t charge = fgGain + delta;
208    charge *= EConst::ElectronCharge();
209
210    // create the list if this does not exist
211    if ( fPmtHits[ch] == NULL ) {
212        fPmtHits[ch] = new vector<PmtSignal*>;
213    }
214
215    // create the PmtSignal and add it to the list
216    PmtSignal* sig = new PmtSignal(ph.time,charge,fgWidth,GetUniqueId(ch),ch+1);
217    fPmtHits[ch]->push_back( sig );
218
219    SetState(kPmtFilling);
220
221    ph.madeSignal = kTRUE;
222
223    // add this level of information to photon history in root file
224    if ( EEvent::GetCurrent() ) {
225        EDetectorPhotonAdder a(&ph,sig,kFALSE);
226        EEvent::GetCurrent()->Fill(a);
227    }
228
229    // keep memory of the time interval of this event
230    if ( sig->Time() > fEndTime )
231        fEndTime = sig->Time();
232    if ( sig->Time() < fStartTime )
233        fStartTime = sig->Time();
234
235    SetEmpty( kFALSE );
236
237    return kTRUE;
238}
Note: See TracBrowser for help on using the repository browser.