GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GeantLMOF.cpp
Go to the documentation of this file.
1 
2 
3 #ifndef ROOT_TString
4 #include "TString.h"
5 #endif
6 
7 #ifndef ROOT_TObjArray
8 #include "TObjArray.h"
9 #endif
10 
11 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,0)
12 #include "TList.h"
13 #include "TMath.h"
14 #endif
15 
16 #include "GeantLMOF.h"
17 
18 #ifndef Gw_AgataGeometryTransformer
20 #endif
21 
22 #define MAXEMITTED 200
23 #define MAXIMPACTS 1000
24 
25 using namespace std;
26 using namespace Gw;
27 
28 
29 GeantLMOF::GeantLMOF()
30 {
31  SetPath(); fCurrent = -1; fMaxFiles = 0; fStatus = kEmpty; fDistFactor = fEnerFactor = 1.0;
32 
33  fEnergy.reserve(MAXEMITTED); fDx.reserve(MAXEMITTED); fDy.reserve(MAXEMITTED); fDz.reserve(MAXEMITTED);
34  fType.reserve(MAXEMITTED);
35 
36  fNdet.reserve(MAXIMPACTS);
37  fEvNum.reserve(MAXIMPACTS);
38  fNInt.reserve(MAXIMPACTS);
39  fPrimary.reserve(MAXIMPACTS);
40 
41  fEdep.reserve(MAXIMPACTS);
42  fPx.reserve(MAXIMPACTS); fPy.reserve(MAXIMPACTS); fPz.reserve(MAXIMPACTS);
43  fNseg.reserve(MAXIMPACTS);
44 
45  fGamma = NULL; fFastOut = false; SetRecoil();
46 }
47 
48 GeantLMOF::~GeantLMOF()
49 {
50  if ( fGamma ) delete fGamma; fGamma = NULL;
51 }
52 
53 TGeoVolume *GeantLMOF::ImportAgataG4(const char *asolid, const char *aclust, const char *aeuler, const char */*top*/)
54 {
55  return AgataGeometryTransformer::ImportAgata(asolid, aclust, aeuler);
56 }
57 
58 void GeantLMOF::ShowCurrentConditions()
59 {
60  cout << "--> Energy Factor " << fEnerFactor << " and Distance Factor " << fDistFactor << endl;
61  cout << "--> Path to data:\n\t" << fPath << endl;
62  cout << "--> Chain of files: " << endl;
63  for (int i = 0; i < fMaxFiles; i++ ) {
64  if ( i == fCurrent ) cout << " [c] ";
65  else cout << " [ ] ";
66  cout << fEventsRead[i] << " events read in " << fFileName[i] << endl;
67  }
68  cout << "--> Recoil: " << fRecoilBeta << " " << fRecoilSigma << " " << fRecoilDx << " " << fRecoilDy << " " << fRecoilDz << " " << fRecoilAngle << endl;
69 }
70 
71 void GeantLMOF::ShowCurrentEvent()
72 {
73  UInt_t i;
74 
75  cout << "list of emmited particles " << endl;
76  for ( i = 0; i < fNbEmitted; i++ ) {
77  cout << " " << fType[i]
78  << " " << fEnergy[i]
79  << " " << fDx[i]
80  << " " << fDy[i]
81  << " " << fDz[i]
82  << " " << fEvNum[i] << endl;
83  }
84  cout << "list of impacts " << endl;
85  for ( i = 0; i < fNbImpacts; i++ ) {
86  cout << " " << fNdet[i]
87  << " " << fEdep[i]
88  << " " << fPx[i]
89  << " " << fPy[i]
90  << " " << fPz[i]
91  << " " << fNseg[i]
92  << " " << fPrimary[i] << endl;
93  }
94 }
95 
96 
97 void GeantLMOF::ReadHeader()
98 {
99  fStatus = kGood;
100  while( fInfile.good() ) {
101 
102  // to get a new line
103  for (int i = 0; i < MAXCHARACTER; i++) { buf[i] = 0; }
104  fInfile.getline(buf,MAXCHARACTER);
105 
106  TString id(buf,MAXCHARACTER);
107  if ( id.Contains("RECOIL") ) {
108  istringstream theline(buf+6);
109  theline.clear();
110  theline >> fRecoilBeta >> fRecoilSigma >> fRecoilDx >> fRecoilDy >> fRecoilDz >> fRecoilAngle;
111  }
112  if ( id.Contains("DISTFACTOR") ) {
113  istringstream theline(buf+10);
114  theline.clear();
115  theline >> fDistFactor;
116  }
117  if ( id.Contains("ENERFACTOR") ) {
118  istringstream theline(buf+10);
119  theline.clear();
120  theline >> fEnerFactor;
121  }
122  // look for beginning of events
123  if ( buf[0] == '$' ) { return; }
124  }
125  cout << " Cannot find beginning of events $ !! " << endl;
126  fInfile.close(); fInfile.clear(); fStatus = kFail; // nothing has been found, so status is kFail
127 }
128 
129 void GeantLMOF::NextFile()
130 {
131  if ( fMaxFiles == 0 ) { fStatus = kEmpty; return; }
132 
133  if ( fInfile.is_open() ) { fInfile.close(); fInfile.clear(); } // in case the user wants to switch in a middle of a file
134  if ( fCurrent < fMaxFiles ) {
135  Int_t tmp = fCurrent;
136  for (Int_t i = fCurrent+1; i < fMaxFiles; i++ ) { // look for a next good file
137 
138  std::string fullname;
139  fullname = fPath; fullname += fFileName[i]; fInfile.open(fullname.data());
140 
141  if ( fInfile.is_open() ) { ReadHeader(); if (fStatus==kGood ) { tmp = i; break; } }
142  } // i
143  if ( tmp == fCurrent ) { fStatus = kEoE; } // fCurrent is the last file
144  else { fCurrent = tmp; }
145  }
146  else { fStatus = kEoE; return; }
147 }
148 
149 UInt_t GeantLMOF::OnlyType(const GeantLMOF &input, Int_t typemin, Int_t typemax)
150 {
151  fNbImpacts = fNbEmitted = 0;
152  for (UInt_t i = 0; i < input.fNbImpacts; i++) { // to remove particles that are not of selected Types
153  if ( input.fType[input.fPrimary[i]] > typemin && input.fType[input.fPrimary[i]] < typemax + 1 ) {
154  fNdet[fNbImpacts] = input.fNdet[i];
155  fEdep[fNbImpacts] = input.fEdep[i];
156  fPx[fNbImpacts] = input.fPx[i];
157  fPy[fNbImpacts] = input.fPy[i];
158  fPz[fNbImpacts] = input.fPz[i];
159  fNseg[fNbImpacts] = input.fNseg[i];
160  fNInt[fNbImpacts] = input.fNInt[i];
161 
162  bool anew = true;
163  for(UInt_t j = 0; j < fNbEmitted; j++ ) { // keep a copy of the emitted if not already done
164  if ( input.fEvNum[i] == fEvNum[j] ) { anew = false; fPrimary[fNbImpacts] = j; break; }
165  }
166  if ( anew ) {
167  fType[fNbEmitted] = input.fType[input.fPrimary[i]];
168  fEnergy[fNbEmitted] = input.fEnergy[input.fPrimary[i]];
169  fDx[fNbEmitted] = input.fDx[input.fPrimary[i]];
170  fDy[fNbEmitted] = input.fDy[input.fPrimary[i]];
171  fDz[fNbEmitted] = input.fDz[input.fPrimary[i]];
172  fEvNum[fNbEmitted] = input.fEvNum[input.fPrimary[i]];
173 
174  fPrimary[fNbImpacts] = fNbEmitted++;
175  }
176  fNbImpacts++;
177  }
178  } // i
179 
180  return fNbImpacts;
181 }
182 
184 {
185  if ( tracker == NULL ) { return; }
186 
187  // to convert GeantLMOF units in tracker units
188  Double_t efactor = GetEnerFactor() / tracker->GetEnerFactor();
189  Double_t pfactor = GetDistFactor() / tracker->GetDistFactor();
190 
191  if ( fFastOut == true ) { // supposed to be only gammas
192  tracker->SetEvent(fNbImpacts,&fEdep[0],&fPx[0],&fPy[0],&fPz[0],efactor,pfactor);
193  }
194  else { // to be sure only impacts coming from gammas are there
195  if ( fGamma == NULL ) {
196  fGamma = new GeantLMOF();
197  }
198  fGamma->OnlyType((*this));
199  tracker->SetEvent(fGamma->NbImpacts(),&fGamma->GetEdep()[0],
200  &fGamma->GetPx()[0],&fGamma->GetPy()[0],&fGamma->GetPz()[0],efactor,pfactor);
201  }
202 }
203 
204 
205 Bool_t GeantLMOF::NextEvent(UInt_t asked_mult)
206 {
207  Int_t id;
208 
209  // does not read until status is good !
210  // if status good, the header part has already been read and the first event is to be read
211  if ( !fInfile.is_open() || !fInfile.good() || fStatus != kGood ) { NextFile(); if ( fStatus != kGood ) return kFALSE; }
212 
213  // Reset the current event
214  UInt_t mult = asked_mult;
215  fNbEmitted = 0;
216  fNbImpacts = 0;
217  while( fInfile.good() ) {
218 
219  Long_t fp = fInfile.tellg();
220 
221  // to get the next line
222  for (int i = 0; i < MAXCHARACTER; i++) { buf[i] = 0; }
223  fInfile.getline(buf,MAXCHARACTER); istringstream theline(buf); theline.clear();
224 
225  theline >> id;
226  if ( id == -100 && fNbEmitted > 0 ) { // next event .. so stop reading this one
227  fEventsRead[fCurrent]++;
228  break;
229  }
230  // just to be sure that one are not trying to build events on an already formated file
231  if ( id == -100 ) { mult = kMaxUInt; continue; }
232 
233  if ( id == -101 ) { // source velocity
234  if ( gDebug == 1 ) cout << "New source velocity (-101) ... not yet treated " << endl; continue;
235  }
236  if ( id == -102 ) { // source position
237  if ( gDebug == 1 ) cout << "New source position (-102) ... not yet treated " << endl; continue;
238  }
239  if ( id == -103 ) { // fTime emission
240  if ( gDebug ) cout << "New fTime emission (-103) ... not yet treated " << endl; continue;
241  }
242  if ( id >= 0 ) { // id is the detector number
243  if ( gDebug == 1 ) cout << " Start new impact " << fNbEmitted << endl;
244 
245  Double_t e, x, y, z;
246  Int_t n;
247  theline >> e; theline >> x >> y >> z; theline >> n;
248 
249  fNdet[fNbImpacts] = id;
250  fEdep[fNbImpacts] = e;
251  fPx[fNbImpacts] = x;
252  fPy[fNbImpacts] = y;
253  fPz[fNbImpacts] = z;
254  fNseg[fNbImpacts] = n;
255 // fPrimary[fNbImpacts] = fEvNum[fNbEmitted-1];
256  fPrimary[fNbImpacts] = fNbEmitted-1;
257 
258  fNbImpacts++;
259 
260  if ( gDebug == 1 ) cout << "End new impact " << endl;
261  }
262  if ( id < 0 ) { // a new particle has been emitted
263  if ( gDebug == 1 ) cout << "Start new particle " << endl;
264 
265  Double_t e, x, y, z;
266  Int_t n;
267  theline >> e; theline >> x >> y >> z; theline >> n;
268 
269  fType[fNbEmitted] = -id;
270  fEnergy[fNbEmitted] = e;
271  fDx[fNbEmitted] = x;
272  fDy[fNbEmitted] = y;
273  fDz[fNbEmitted] = z;
274  fEvNum[fNbEmitted] = n;
275 
276  fNbEmitted++;
277 
278  if ( gDebug == 1 ) cout << "End new particle " << id << " " << fNbEmitted << endl;
279  }
280  // to read files without beginning of events flags ... rewind the last line
281  if ( fNbEmitted > mult ) { fInfile.seekg(fp,ios::beg); fNbEmitted--; fEventsRead[fCurrent]+=1.0; break; }
282 
283  // to avoid out_of_range in vectors
284  if ( fNbEmitted > MAXEMITTED - 1 || fNbImpacts > MAXIMPACTS - 1 ) {
285  cout << " WARNING - Too much emitted particles " << fNbEmitted << " or impacts " << fNbImpacts << endl;
286  fStatus = kFail;
287  return kFALSE;
288  }
289  } // while in_good
290  if ( fNbEmitted > 0 ) return kTRUE;
291  return kFALSE;
292 }
293 
294 
295 
Double_t GetDistFactor() const
Internal unit system for lengths and energies.
Definition: GammaTracker.h:83
#define MAXCHARACTER
Definition: GeantLMOF.h:18
std::istream & operator>>(std::istream &is, ADF::FactoryItem &item)
Base class to build tracker families.
Definition: GammaTracker.h:29
Double_t GetEnerFactor() const
Definition: GammaTracker.h:84
virtual UInt_t SetEvent(UInt_t n, const Double_t *e, const Double_t *x, const Double_t *y, const Double_t *z, Double_t efactor=1.0, Double_t pfactor=1.0)
friend LogMessage & clear(LogMessage &)
others
Class to read/decode Geant List Mode Output Files.
Definition: GeantLMOF.h:59
ADF::LogMessage & endl(ADF::LogMessage &log)
#define MAXEMITTED
Definition: GeantLMOF.cpp:22
#define MAXIMPACTS
Definition: GeantLMOF.cpp:23