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