GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
EvapLMOF.cpp
Go to the documentation of this file.
1 
2 #ifndef ROOT_TMath
3 #include "TMath.h"
4 #endif
5 
6 #ifndef ROOT_TVector3
7 #include "TVector3.h"
8 #endif
9 
10 #ifndef ROOT_TLeafS
11 #include "TLeafS.h"
12 #endif
13 #ifndef ROOT_TLeafI
14 #include "TLeafI.h"
15 #endif
16 #ifndef ROOT_TLeafF
17 #include "TLeafF.h"
18 #endif
19 #ifndef ROOT_TLeafB
20 #include "TLeafB.h"
21 #endif
22 
23 #ifndef ROOT_TRandom
24 #include "TRandom.h"
25 #endif
26 
27 #ifndef ROOT_TString
28 #include "TString.h"
29 #endif
30 
31 #include "EvapLMOF.h"
32 
33 TRandom *therand;
34 
35 // anonymous namespace to put EvapOR import that come usiing f2c for some fortran functions of the package
36 //
37 // plm2.f, getang.f
38 //
39 namespace {
40 
41 /* Common Block Declarations */
42 struct xqang_ { Float_t sum[15300] /* was [300][51] */; } xqang_1;
43 
44 /* Table of constant values */
45 static Double_t c_b4 = 1e-15;
46 
47 /* Subroutine */ Int_t plm2_(void)
48 {
49  /* Initialized data */
50  static Float_t bin[3] = { .1667f,.5f,.8333f };
51 
52  /* System generated locals */
53  Long_t i__1;
54  Double_t d__1;
55 
56  /* Builtin functions */
57  // Double_t sqrt(Double_t), d_sign(Double_t *, Double_t *);
58 
59  /* Local variables */
60  static Long_t l, m, n;
61  static Double_t z__;
62  static Long_t ii, ik, jk, ll, mm;
63  static Double_t pl[900] /* was [30][30] */;
64  static Long_t iang;
65  static Double_t temp, plmm, dsum[15300] /* was [300][51] */;
66  static Long_t iiter;
67 
68 /* CALCULATE ASSOCIATED LEGENDRE FUNTIONS AND FORM TABLE OF RUNNING */
69 /* DSUMS FOR LATER SELECTION OF ANGLE. */
70 /* TO SAVE SPACE THE RUNNING DSUM DSUM(N,IANG) IS STORED FOR EACH */
71 /* P(L,M) AT N=L*(L-1)/2+M . THE POLYNOMIAL IS OF ORDER (L-1,M-1). */
72 /* IANG IS A COS(ANGLE) INDEX FROM .05 TO .95 IN 50 STEPS. */
73 /* ******** WARNING. FOR M = L AND L ABOVE 20 RESULTS ARE INACCURATE. */
74 /* THIS IS A DUPLICATE OF THE SUBROUTINE PLM, IN THE MAIN PROGRAM */
75 /* A FINER GRANULARITY IN THE ANGLE RANGE IS REQUIRED HERE. */
76 
77 /* THIS FORMS FACTORIALS FOR LATER C.G. CALCULATIONS */
78  for (ii = 1; ii <= 3; ++ii) {
79  bin[ii - 1] *= .02f;
80  }
81  for (ik = 1; ik <= 300; ++ik) {
82  for (jk = 1; jk <= 50; ++jk) {
83 /* L10: */
84  dsum[ik + jk * 300 - 301] = 0.f;
85  }
86  }
87  for (iang = 1; iang <= 50; ++iang) {
88  for (iiter = 1; iiter <= 3; ++iiter) {
89  z__ = iang * .02f - bin[iiter - 1];
90  pl[0] = 1.f;
91  pl[1] = z__;
92 /* Computing 2nd power */
93  d__1 = z__;
94  temp = 1.f - d__1 * d__1;
95  pl[31] = TMath::Sqrt(temp);
96  if (TMath::Abs(pl[31]) < 1e-15) {
97  pl[31] = TMath::Sign(c_b4, pl[31]);
98  }
99 /* Computing 2nd power */
100  d__1 = z__;
101  pl[2] = (d__1 * d__1 * 3.f - 1.f) * .5f;
102  pl[32] = pl[31] * 3.f * z__;
103  pl[62] = temp * 3.f;
104  for (l = 4; l <= 24; ++l) {
105  ll = l - 1;
106  pl[l - 1] = (((ll << 1) - 1) * z__ * pl[l - 2] - (ll - 1) *
107  pl[l - 3]) / ll;
108  pl[l + 29] = (((ll << 1) - 1) * z__ * pl[l + 28] - ll * pl[l
109  + 27]) / (ll - 1);
110  i__1 = l;
111  for (m = 3; m <= i__1; ++m) {
112  mm = m - 1;
113  pl[l + m * 30 - 31] = (ll + mm - 1) * pl[l - 1 + (m - 1) *
114  30 - 31] - (ll - mm + 1) * z__ * pl[l + (m - 1) *
115  30 - 31];
116  pl[l + m * 30 - 31] /= pl[31];
117 /* INDEX OF (L,M) = N */
118 /* L20: */
119  }
120  }
121  for (l = 1; l <= 24; ++l) {
122  i__1 = l;
123  for (m = 1; m <= i__1; ++m) {
124  plmm = pl[l + m * 30 - 31] * 1e-10f;
125  if (l > 11 && m > (l - 1) / 2) {
126  plmm = pl[l + m * 30 - 31] * 1e-20f;
127  }
128  n = l * (l - 1) / 2 + m;
129 /* L30: */
130 /* Computing 2nd power */
131  d__1 = plmm;
132  dsum[n + iang * 300 - 301] += d__1 * d__1;
133  }
134  }
135 /* L40: */
136  }
137  }
138 
139  for (n = 1; n <= 300; ++n) {
140  for (iang = 2; iang <= 50; ++iang) {
141 /* L50: */
142  dsum[n + iang * 300 - 301] += dsum[n + (iang - 1) * 300 - 301];
143  }
144  if (dsum[n + 14699] == 0.f) {
145  dsum[n + 14699] = 1e-20;
146  }
147  for (iang = 1; iang <= 50; ++iang) {
148  dsum[n + iang * 300 - 301] /= dsum[n + 14699];
149 /* L60: */
150  xqang_1.sum[n + iang * 300 - 301] = dsum[n + iang * 300 - 301];
151  }
152  }
153 
154  return 0;
155 } /* plm2_ */
156 
157 /* Subroutine */ Int_t getang_(Int_t *l, Int_t *m, Float_t *ct, Float_t *theta, Float_t *phi)
158 {
159  /* Initialized data */
160  static Short_t isetup = 0;
161 
162  /* Builtin functions */
163  // double Double_t acos(Double_t);
164 
165  /* Local variables */
166  static Int_t n;
167  static Float_t x;
168  static Int_t im, ict;
169 // static Int_t iogr;
170 
171 /* GETANG chooses an angle for emission randomly based on the (l,m) */
172 /* values from pace. igrid gives the number of cos theta bins (in 0-90 */
173 /* range. */
174  if (isetup == 0) {
175  isetup = 1;
176  plm2_();
177  therand = new TRandom(0); // replace raninit_rtc__(&c__2) as a random generator
178 // iogr = 50;
179  }
180  im = TMath::Abs(*m);
181  n = (*l) * (*l + 1) / 2 + im + 1;
182  x = therand->Rndm(); // ranf_(&idummy);
183  for (ict = 1; ict <= 50; ++ict) {
184  *ct = (Float_t) ict;
185  if (x <= xqang_1.sum[n + ict * 300 - 301]) {
186  goto L100;
187  }
188  }
189 L100:
190 // *ct = (*ct - ranf_(&idummy)) * .02f;
191  *ct = (*ct - therand->Rndm()) * .02f;
192  x = therand->Rndm(); // ranf_(&idummy);
193  if (x < .5f) {
194  *ct = -(*ct);
195  }
196 // *phi = ranf_(&idummy) * 6.2831853999999998f;
197  *phi = therand->Rndm() * 6.2831853999999998f;
198  *theta = TMath::ACos(*ct);
199  return 0;
200 } /* getang_ */
201 
202 } // anonymous namespace for EvapOR like functions
203 
204 
205 using namespace std;
206 using namespace Gw;
207 
208 Short_t EvapLMOF::VERBOSE = 0;
209 const Short_t EvapLMOF::MAXCASCADE; const Short_t EvapLMOF::MAXPARTICLES;
210 
211 EvapLMOF::EvapLMOF() : fHeader(NULL), fGlobalRecord(NULL), fIdRecord(NULL), fDataRecord(NULL), fIdOnly(false), fInfile(NULL), fCurrent(-1), fMaxFiles(0), fStatus(kEmpty)
212 {
213  SetPath();
214 }
215 
217 {
218  if ( EvapLMOF::VERBOSE ) cout << " IN EvapLMOF::~EvapLMOF()" << endl;
219 
220  if ( fHeader != NULL ) {
221  if ( fHeader->IsStatus(Gws::Buffer::kCorrupt) && EvapLMOF::VERBOSE ) cout << " Header buffer corrupted " << endl;
222  delete fHeader; fHeader = NULL;
223  }
224  if ( fGlobalRecord != NULL ) {
225  if ( fGlobalRecord->IsStatus(Gws::Buffer::kCorrupt) && EvapLMOF::VERBOSE ) cout << " Global buffer corrupted " << endl;
226  delete fGlobalRecord; fGlobalRecord = NULL;
227  }
228  if ( fIdRecord != NULL ) {
229  if ( fIdRecord->IsStatus(Gws::Buffer::kCorrupt) && EvapLMOF::VERBOSE ) cout << " Id buffer corrupted " << endl;
230  delete fIdRecord; fIdRecord= NULL;
231  }
232  if ( fDataRecord != NULL ) {
233  if ( fDataRecord->IsStatus(Gws::Buffer::kCorrupt) && EvapLMOF::VERBOSE ) cout << " Data buffer corrupted " << endl;
234  delete fDataRecord; fDataRecord = NULL;
235  }
236 
237  if ( fInfile ) { ::fclose(fInfile); fInfile = NULL; }
238 
239  if ( EvapLMOF::VERBOSE ) cout << " OUT EvapLMOF::~EvapLMOF()" << endl;
240 }
241 
242 void EvapLMOF::ShowCurrentConditions(std::ostream &out)
243 {
244  out << "--> Path to data:\n\t" << fPath << endl;
245  out << "--> Chain of files: " << endl;
246  for (int i = 0; i < fMaxFiles; i++ ) {
247  if ( i == fCurrent ) cout << " [c] ";
248  else out << " [ ] ";
249  out << fEventsRead[i] << " events read in " << fFileName[i] << endl;
250  }
251  if ( fWarning != "" ) out << " Warning: " << fWarning.Data() << endl;
252  if ( fStatus == kFail ) out << " Last Error: " << fError.Data() << endl;
253  if ( fStatus == kEoE ) out << " All events have been read " << endl;
254 }
255 
256 void EvapLMOF::ShowCurrentEvent(std::ostream &out)
257 {
258  Short_t i;
259 
260  out << " -- GLOBAL RECORD " << endl;
261  out << "AC: " << fGlobal.AC << ", ZC: " << fGlobal.ZC << ", NCASC: " << fGlobal.NCASC << ", MDIR: " << fGlobal.MDIR
262  << ", JCAS: " << fGlobal.JCASC << ", ENER: " << fGlobal.ENER << ", SIGMA: " << fGlobal.SIGMA
263  << ", VRC: " << fGlobal.VRC << ", MAX_P: " << fGlobal.MAX_P << endl;
264  out << " -- ID RECORD " << endl;
265  out << "MG: " << fId.MG << ", EE: " << fId.EE << ", JE: " << fId.JE << ", L: " << fId.L
266  << ", Z: " << fId.Z << ", N: " << fId.N << ", NUM: " << fId.NUM
267  << ", WT: " << fId.WT << ", FIS: " << fId.FIS << endl;
268 
269  if ( fIdOnly ) return; // no need to show the full cascade in idonly mode
270 
271  out << " -- DATA RECORD " << endl;
272  for ( i = 0; i < fId.NUM; i++ ) { // cascade
273  out << "Cascade " << i << endl << "MODE: " << fData.MODE[i] << ", EI: " << fData.EI[i] << ", JI: " << fData.JI[i] << ", EP: " << fData.EP[i] << ", LP: " << fData.LP[i] << ", MP: " << fData.MP[i] << endl;
274  out << "VE0: " << fKin.VE[i][0] << ", VE1: " << fKin.VE[i][1] << ", VE2: " << fKin.VE[i][2] << ", THETA: " << fKin.THETA[i] << ", PHI: " << fKin.PHI[i] << ", EEJ: " << fKin.EEJ[i] << ", JF: " << fKin.JF[i] << endl;
275  }
276  for ( i = 1; i < MAXPARTICLES; i++ ) { // statitics per cascade
277  if ( fData.MUL[i] > 0 ) out << " MODE " << i << " MULT: " << fData.MUL[i] << ", ES: " << fData.ES[i] << ", DJ: " << fData.DJ[i] << endl;
278  }
279  out << "ZB: " << fKin.ZB << ", AB: " << fKin.AB << ", ER: " << fKin.ER << ", VO0: " << fKin.V0[0] << ", VO1: " << fKin.V0[1] << ", VO2: " << fKin.V0[2] << endl;
280 }
281 
282 void EvapLMOF::SetRecord(Gws::Memory::EEndian e)
283 {
284  if ( EvapLMOF::VERBOSE ) cout << " IN EvapLMOF::SetRecord(Gws::Memory::EEndian e)" << endl;
285 
286  if ( fHeader != NULL ) { // already exist
287  if ( fHeader->IsBytes(e) ) { // with the good endian type
288  fHeader->Reset();
289  }
290  else { delete fHeader; fHeader = NULL; }
291  }
292  if ( fHeader == NULL ) { fHeader = Gws::Buffer::New(e,4); }
293 
294  if ( fGlobalRecord != NULL ) { // already exist
295  if ( fGlobalRecord->IsBytes(e) ) { // with the good endian type
296  fGlobalRecord->Reset();
297  }
298  else { delete fGlobalRecord; fGlobalRecord = NULL; }
299  }
300  if ( fGlobalRecord == NULL ) { fGlobalRecord = Gws::Buffer::New(e,40+4); }
301  // 40+4 because of the additionnal int at the end that corresponds to the length of the buffer
302 
303  if ( fIdRecord != NULL ) { // already exist
304  if ( fIdRecord->IsBytes(e) ) { // with the good endian type
305  fIdRecord->Reset();
306  }
307  else { delete fIdRecord; fIdRecord = NULL; }
308  }
309  if ( fIdRecord == NULL ) { fIdRecord = Gws::Buffer::New(e,14+4); }
310  // 14+4 because of the additionnal int at the end that corresponds to the length of the buffer
311 
312  if ( fDataRecord != NULL ) { // already exist
313  if ( fDataRecord->IsBytes(e) ) { // with the good endian type
314  fDataRecord->Reset();
315  }
316  else { delete fDataRecord; fDataRecord = NULL; }
317  }
318  if ( fDataRecord == NULL ) { fDataRecord = Gws::Buffer::New(e,8*MAXCASCADE); }
319 
320  if ( EvapLMOF::VERBOSE ) cout << " OUT EvapLMOF::SetRecord(Gws::Memory::EEndian e)" << endl;
321 }
322 
323 void EvapLMOF::ReadHeader()
324 {
325  if ( EvapLMOF::VERBOSE ) cout << " IN EvapLMOF::ReadHeader()" << endl;
326 
327  // read magic numbers to determine if it is a .pax file and set the endian type.
328  Int_t magic1 = 0, magic2 = 0;
329 
330  fStatus = kGood;
331 
332  ::fread(&magic1,sizeof(Int_t),1,fInfile); ::fread(&magic2,sizeof(Int_t),1,fInfile);
333  if ( ::ferror(fInfile) == 0 ) {
334  ::rewind(fInfile); // rewind to start at the beginning of the file
335  if ( magic1 == 0x00000028 && magic2 == 0x77777777 ) { /* cout << "LITTLE" << endl; */ SetRecord(Gws::Memory::kLittle); return; }
336  if ( magic1 == 0x28000000 && magic2 == 0x77777777 ) { /* cout << "BIG" << endl; */ SetRecord(Gws::Memory::kBig); return; }
337  }
338  ::fclose(fInfile); fInfile = NULL; fStatus = kFail; // nothing good has been found, so status is kFail
339 
340  if ( EvapLMOF::VERBOSE ) cout << " OUT EvapLMOF::ReadHeader()" << endl;
341 }
342 
344 {
345  if ( EvapLMOF::VERBOSE ) cout << " IN EvapLMOF::NextFile()" << endl;
346 
347  if ( fMaxFiles == 0 ) { fStatus = kEmpty; return; }
348 
349  // in case the user wants to switch in a middle of a file
350  if ( fInfile ) { if ( ::ferror(fInfile) ) cout << "WARNING: ferror detected in EvapLMOF::NextFile" << endl; ::fclose(fInfile); fInfile = NULL; }
351 
352  if ( fCurrent < fMaxFiles ) {
353  Int_t tmp = fCurrent;
354  for (Int_t i = fCurrent+1; i < fMaxFiles; i++ ) { // look for a next good file
355 
356  std::string fullname;
357  fullname = fPath; fullname += fFileName[i]; fInfile = ::fopen(fullname.data(),"r");
358 
359  if ( fInfile ) { ReadHeader(); if (fStatus==kGood ) { tmp = i; break; } }
360  } // i
361  if ( tmp == fCurrent ) { fStatus = kEoE; } // fCurrent is the last file
362  else { fCurrent = tmp; }
363  }
364  else { fStatus = kEoE; }
365 
366  if ( EvapLMOF::VERBOSE ) cout << " OUT EvapLMOF::NextFile()" << endl;
367 }
368 
369 Bool_t EvapLMOF::ReadGlobal()
370 {
371  Int_t id;
372 
373  ::fread(fGlobalRecord->GetBuffer(),fGlobalRecord->Size(),1,fInfile); if ( ::ferror(fInfile) != 0 ) return kFALSE;
374 
375  // start decoding
376  fGlobalRecord->SetOffset();
377  (*fGlobalRecord) >> id; if ( id != 0x77777777 ) { fError = " Wrong GLOBAL record id "; return kFALSE; } // check if it is a global record
378 
379  (*fGlobalRecord) >> fGlobal.ZC;
380  (*fGlobalRecord) >> fGlobal.AC;
381  (*fGlobalRecord) >> fGlobal.NCASC;
382  (*fGlobalRecord) >> fGlobal.MDIR;
383  (*fGlobalRecord) >> fGlobal.JCASC;
384  (*fGlobalRecord) >> fGlobal.ENER;
385  (*fGlobalRecord) >> fGlobal.SIGMA;
386  (*fGlobalRecord) >> fGlobal.VRC;
387  (*fGlobalRecord) >> fGlobal.MAX_P;
388 
389  return ( !fGlobalRecord->IsStatus(Gws::Buffer::kFail) );
390 }
391 
392 Bool_t EvapLMOF::ReadId()
393 {
394  Short_t id, idok = 0xFFFF, idfission = 0xFFEE, idnodata = 0xFFFD; Char_t c; UChar_t uc;
395 
396  ::fread(fIdRecord->GetBuffer(),fIdRecord->Size(),1,fInfile); if ( ::ferror(fInfile) != 0 ) return kFALSE;
397 
398  // start decoding
399  fIdRecord->SetOffset();
400  (*fIdRecord) >> id;
401  if ( !(id == idok || id == idfission || id == idnodata) ) { fError = " Wrong ID record "; return kFALSE; } // check if it is a valid id record
402 
403  if ( id == idfission ) fId.FIS = kTRUE; // the cascade ends up by fission
404  else fId.FIS = kFALSE;
405 
406  fId.MG = 0;
407 
408  (*fIdRecord) >> id; fId.EE = id;
409  (*fIdRecord) >> uc; fId.JE = Short_t(uc);
410  (*fIdRecord) >> uc; fId.L = Short_t(uc);
411  (*fIdRecord) >> uc; fId.N = Short_t(uc);
412  (*fIdRecord) >> c; fId.Z = Short_t(c); if ( c < 0 ) { fId.Z = - Short_t(c); fId.FIS = kTRUE; } // -Z if fission (from evapor sources)
413  (*fIdRecord) >> fId.WT;
414  (*fIdRecord) >> fId.NUM;
415 
416  if ( id == idnodata ) fId.NUM = 0; // no data record exists
417 
418  return ( !fIdRecord->IsStatus(Gws::Buffer::kFail) );
419 }
420 
421 Bool_t EvapLMOF::ReadData()
422 {
423  Bool_t decode;
424 
425  // z,n for the different particles
426  const Short_t zp[MAXPARTICLES] = { 0,0,1,2,1,1,2,3,8,0,0,0 };
427  const Short_t ap[MAXPARTICLES] = { 0,1,1,4,2,3,3,6,16,0,0,0 };
428 
429  Int_t lengthstart, lengthend; Short_t id, dz, da; Char_t c;
430 
431  decode = kTRUE;
432  // read the real buffer size
433  ::fread(fHeader->GetBuffer(),fHeader->Size(),1,fInfile); fHeader->SetOffset(); (*fHeader) >> lengthstart;
434 
435  if ( lengthstart > (Int_t)fDataRecord->Size() || fId.NUM > MAXCASCADE )
436  { fWarning = " Large cascade reached and skipped "; ::fseek(fInfile,lengthstart,SEEK_CUR); decode = kFALSE; }
437  else
438  ::fread(fDataRecord->GetBuffer(),lengthstart,1,fInfile); // read all cascades in one operation
439 
440  // check if equal to the header part
441  ::fread(fHeader->GetBuffer(),fHeader->Size(),1,fInfile); fHeader->SetOffset(); (*fHeader) >> lengthend;
442 
443  if ( ::ferror(fInfile) != 0 ) { fError = " PB to read data record from file "; return kFALSE; }
444  if ( lengthstart != lengthend ) { fError = " Start and end size of data record don't match "; return kFALSE; }
445 
446  if ( fIdOnly || decode == kFALSE ) return kTRUE; // in case the detail of the cascade is not needed
447 
448  // rewind buffer to start getting data
449  fDataRecord->SetOffset();
450  ::memset(&fData,0,sizeof(fData)); ::memset(&fKin,0,sizeof(fKin)); fKin.ZB = fId.Z; fKin.AB = fId.Z + fId.N; // starts from residual nucleus
451 
452  // first loop to fill the cascade and compute some values
453  for (Short_t i = 0; i < fId.NUM; i++ ) {
454  (*fDataRecord) >> id; fData.EP[i] = id / 10.;
455  (*fDataRecord) >> id; fData.EI[i] = id;
456 
457  (*fDataRecord) >> c; fData.MODE[i] = Short_t(c);
458  (*fDataRecord) >> c; fData.JI[i] = Short_t(c);
459  (*fDataRecord) >> c; fData.MP[i] = Short_t(c);
460  (*fDataRecord) >> c; fData.LP[i] = Short_t(c);
461 
462 // if ( fId.MODE[i] < 1 || fId.MODE[i] > MAXPARTICLES-1 ) return kFALSE; // unknown type
463  if ( fData.MODE[i] <= fGlobal.MAX_P ) { // this is a charged particle
464  dz = zp[fData.MODE[i]];
465  da = ap[fData.MODE[i]];
466  }
467  else { // this is a gamma
468  dz = 0;
469  da = 0;
470  }
471 
472  fKin.ZB += dz;
473  fKin.AB += da;
474 
475  if ( fData.MODE[i] == fGlobal.MAX_P + 4 ) { // E2 yrast cascade
476  fData.MUL[fGlobal.MAX_P+4] = fData.LP[i];
477  fData.LP[i] = 0 ;
478  fData.ES[fGlobal.MAX_P+4] = fData.EI[i];
479  }
480  else {
481  fData.MUL[fData.MODE[i]] += 1 ;
482  fData.ES[fData.MODE[i]] += fData.EP[i];
483  }
484  if ( fData.MODE[i] == fGlobal.MAX_P + 3 ) fId.FIS = kTRUE; // ends up by fission ..
485  }
486  // to set the gamma-rays multiplicity
487  fId.MG = fData.MUL[fGlobal.MAX_P+1] + fData.MUL[fGlobal.MAX_P+2] + fData.MUL[fGlobal.MAX_P+4];
488 
489  // residual nucleus
490  fKin.V0[0] = fGlobal.VRC * fGlobal.MDIR;
491  fKin.V0[1] = 0.0;
492  fKin.V0[2] = fGlobal.VRC * (1.0 - fGlobal.MDIR);
493 
494  Int_t ac_run = fGlobal.AC, ar = ac_run, ml; Float_t vl[3], ct, avl, fug;
495 
496  const Float_t massu = 931.5;
497 
498  for (Short_t i = 0; i < fId.NUM; i++ ) {
499 
500  Short_t jmode = fData.MODE[i]; // particle type
501 
502  if ( i < fId.NUM-1 ) {
503  fData.DJ[jmode] = fData.DJ[jmode] + fData.JI[i] - fData.JI[i+1];
504  fKin.JF[i] = fData.JI[i+1];
505  ml = fData.MP[i] - fData.MP[i+1];
506  }
507  else { // last data record
508  if( jmode <= fGlobal.MAX_P ) { // charged particle
509  fKin.JF[i] = fData.JI[i]; ml = 0;
510  }
511  else {
512  if( jmode == (fGlobal.MAX_P + 1) ) { fKin.JF[i] = fData.JI[i]; ml = 0; }
513  else {
514  if( jmode == (fGlobal.MAX_P + 2) ) {
515  ml = 0;
516  fKin.JF[i] = fData.JI[i]-2; fData.DJ[jmode] += 2;
517  }
518  }
519  }
520  }
521  Int_t ll = fData.LP[i], al; // Short_t mdr = mdir;
522  al = 0;
523  if ( jmode <= fGlobal.MAX_P ) al = ap[jmode] ;
524  if( al > 0.0 ) {
525  getang_(&ll,&ml,&ct,&fKin.THETA[i],&fKin.PHI[i]);
526 
527  Double_t st = TMath::Sin(fKin.THETA[i]);
528  Double_t cp = TMath::Cos(fKin.PHI[i]);
529  Double_t sp = TMath::Sin(fKin.PHI[i]);
530 
531  ar = ac_run - al; avl = TMath::Sqrt(2.*fData.EP[i]/(massu*al)); fug= al / ar ;
532 
533  vl[2] =avl*ct;
534  vl[1] =avl*st*sp;
535  vl[0] =avl*st*cp;
536 
537  for (Int_t j = 0; j < 3; j++ ) {
538  fKin.VE[i][j] = fKin.V0[j] + vl[j];
539  fKin.V0[j] = fKin.V0[j] - fug*vl[j];
540  }
541  ac_run = ar ;
542  }
543  else {
544  for (Int_t j = 0; j < 3; j++ ) {
545  fKin.VE[i][j] = 0.0;
546  }
547  }
548  fKin.EEJ[i] = 0.5 * al * massu * ( fKin.VE[i][0]*fKin.VE[i][0] + fKin.VE[i][1]*fKin.VE[i][1] + fKin.VE[i][2]*fKin.VE[i][2] );
549  } // i
550  fKin.ER = 0.5 * ar * massu * ( fKin.V0[0]*fKin.V0[0] + fKin.V0[1]*fKin.V0[1] + fKin.V0[2]*fKin.V0[2] );
551 
552  return kTRUE;
553 }
554 
556 {
557  if ( EvapLMOF::VERBOSE ) cout << " IN EvapLMOF::Rewind()" << endl;
558 
559  if ( fInfile ) { ::fclose(fInfile); fInfile = NULL; }
560 
561  // change current to 0, reset statistics and load the next file
562  fStatus = kEmpty;
563  fWarning = "";
564  fError = "";
565  fCurrent = -1; for ( Int_t i = 0; i < fMaxFiles; i++ ) { fEventsRead[i] = 0.0; }
566 
567  NextFile();
568 
569  if ( EvapLMOF::VERBOSE ) cout << " OUT EvapLMOF::Rewind()" << endl;
570 }
571 
572 Bool_t EvapLMOF::NextEvent(UInt_t /*i*/)
573 {
574  Int_t bsize; Bool_t isok;
575 
576  // does not read until status is good !
577  // if status good, the header part has already been read and the first event is to be read
578  if ( fInfile == NULL || ::ferror(fInfile) != 0 || fStatus != kGood ) { NextFile(); if ( fStatus != kGood ) return kFALSE; }
579 
580  isok = kTRUE; ::fread(fHeader->GetBuffer(),fHeader->Size(),1,fInfile);
581 
582  if ( ::feof(fInfile) != 0 ) { // apparently eof is detected only when trying to read after the end
583  NextFile();
584  if ( fStatus != kGood ) return kFALSE;
585  else ::fread(fHeader->GetBuffer(),fHeader->Size(),1,fInfile);
586  }
587  if ( ::ferror(fInfile) == 0 ) {
588 
589  fHeader->SetOffset(); (*fHeader) >> bsize ;
590 
591 // cout << " Size " << bsize << endl;
592  if ( bsize == 40 ) { // this is a global record
593 // cout << " Block Record " << endl;
594  if ( ReadGlobal() == kFALSE )
595  { /* cout << " GLOBAL record wrong " << endl; */ fStatus = kFail; return kFALSE; }
596  // a new run has been read, so next record must be identified
597  else { ::fread(fHeader->GetBuffer(),fHeader->Size(),1,fInfile); fHeader->SetOffset(); (*fHeader) >> bsize ; }
598  }
599  if ( bsize == 14 ) { // this is an id record
600  if ( ReadId() == kFALSE ) { /* cout << " ID record wrong " << endl; */ fStatus = kFail; return kFALSE; }
601  else {
602  if ( ReadData() == kFALSE ) {
603  /* cout << " Data record wrong " << endl; */ fStatus = kFail; return kFALSE;
604  }
605  else fEventsRead[fCurrent] += 1.0; // a good event has just been read
606  }
607  }
608  else { fError = "Wrong size at position "; fError += (::ftell(fInfile)); fStatus = kFail; isok = kFALSE; }
609  }
610  else { fStatus = kFail; isok = kFALSE; }
611 
612  return isok;
613 }
614 
615 void EvapLMOF::Scan(UInt_t start, UInt_t end)
616 {
617  UInt_t stop;
618 
619  // to start form the beginning
620  Rewind();
621 
622  // start looping on events
623  stop = 0;
624  for (UInt_t i = 1; i < end+1; i++ ) {
625  if ( NextEvent() == kFALSE ) { stop = i; break; }
626  if ( i >= start+1 ) { cout << " ***** Event # " << i << endl; ShowCurrentEvent(); }
627  }
628  if ( stop != 0 ) {
629  cout << " !!!!! Breaking at Event # " << stop << endl; cout << fError.Data() << endl;
630  }
631 }
632 
633 TLeaf *EvapLMOF::GetLeaf(const char *leafname)
634 {
635  TLeaf *leaf = NULL; TString tmp = leafname;
636 
637  // leaf corresponding to global record
638  if ( tmp == "AC" ) { leaf = new TLeafI(); leaf->SetAddress(&fGlobal.AC); }
639  if ( tmp == "ZC" ) { leaf = new TLeafI(); leaf->SetAddress(&fGlobal.ZC); }
640  if ( tmp == "NCASC" ) { leaf = new TLeafI(); leaf->SetAddress(&fGlobal.NCASC); }
641  if ( tmp == "MDIR" ) { leaf = new TLeafI(); leaf->SetAddress(&fGlobal.MDIR); }
642  if ( tmp == "JCASC" ) { leaf = new TLeafI(); leaf->SetAddress(&fGlobal.JCASC); }
643  if ( tmp == "ENER" ) { leaf = new TLeafF(); leaf->SetAddress(&fGlobal.ENER); }
644  if ( tmp == "SIGMA" ) { leaf = new TLeafF(); leaf->SetAddress(&fGlobal.SIGMA);}
645  if ( tmp == "VRC" ) { leaf = new TLeafF(); leaf->SetAddress(&fGlobal.VRC);}
646  if ( tmp == "MAX_P" ) { leaf = new TLeafI(); leaf->SetAddress(&fGlobal.MAX_P);}
647 
648  // leaf corresponding to ID record
649  if ( tmp == "MG" ) { leaf = new TLeafS(); leaf->SetAddress(&fId.MG); }
650  if ( tmp == "EE" ) { leaf = new TLeafF(); leaf->SetAddress(&fId.EE); }
651  if ( tmp == "JE" ) { leaf = new TLeafF(); leaf->SetAddress(&fId.JE); }
652  if ( tmp == "L" ) { leaf = new TLeafF(); leaf->SetAddress(&fId.L); }
653  if ( tmp == "Z" ) { leaf = new TLeafS(); leaf->SetAddress(&fId.Z); }
654  if ( tmp == "N" ) { leaf = new TLeafS(); leaf->SetAddress(&fId.N); }
655  if ( tmp == "NUM" ) { leaf = new TLeafS(); leaf->SetAddress(&fId.NUM); }
656  if ( tmp == "WT" ) { leaf = new TLeafF(); leaf->SetAddress(&fId.WT); }
657  if ( tmp == "FIS" ) { leaf = new TLeafB(); leaf->SetAddress(&fId.FIS);}
658 
659  // leaf corresponding to data record
660  if ( tmp == "MODE" ) { leaf = new TLeafS(); leaf->SetAddress(fData.MODE); }
661  if ( tmp == "EI" ) { leaf = new TLeafF(); leaf->SetAddress(fData.EI); }
662  if ( tmp == "EP" ) { leaf = new TLeafF(); leaf->SetAddress(fData.EP); }
663  if ( tmp == "JI" ) { leaf = new TLeafS(); leaf->SetAddress(fData.JI); }
664  if ( tmp == "LP" ) { leaf = new TLeafS(); leaf->SetAddress(fData.LP); }
665  if ( tmp == "MP" ) { leaf = new TLeafS(); leaf->SetAddress(fData.MP); }
666  if ( tmp == "MUL" ) { leaf = new TLeafS(); leaf->SetAddress(fData.MUL); }
667  if ( tmp == "ES" ) { leaf = new TLeafF(); leaf->SetAddress(fData.ES); }
668  if ( tmp == "DJ" ) { leaf = new TLeafF(); leaf->SetAddress(fData.DJ);}
669 
670  // leaf corresponding to kinematic record
671  if ( tmp == "V0" ) { leaf = new TLeafF(); leaf->SetAddress(fKin.V0); }
672  if ( tmp == "VE" ) { leaf = new TLeafF(); leaf->SetAddress(fKin.VE); }
673  if ( tmp == "THETA" ){ leaf = new TLeafF(); leaf->SetAddress(fKin.THETA); }
674  if ( tmp == "PHI" ) { leaf = new TLeafF(); leaf->SetAddress(fKin.PHI); }
675  if ( tmp == "ZB" ) { leaf = new TLeafS(); leaf->SetAddress(&fKin.ZB); }
676  if ( tmp == "AB" ) { leaf = new TLeafS(); leaf->SetAddress(&fKin.AB); }
677  if ( tmp == "ER" ) { leaf = new TLeafF(); leaf->SetAddress(&fKin.ER); }
678  if ( tmp == "EEJ" ) { leaf = new TLeafF(); leaf->SetAddress(fKin.EEJ); }
679  if ( tmp == "JF" ) { leaf = new TLeafF(); leaf->SetAddress(fKin.JF);}
680 
681  return leaf;
682 }
683 
684 /*
685 void EvapLMOF::Map()
686 {
687  Int_t bsize, nbglobal, nbid, nbdata, bytesread;
688 
689  // to start form the beginning
690  nbglobal = nbid = nbdata = bytesread = 0; Rewind();
691 
692  // does not read until status is good !
693  // if status good, the header part has already been read and the first event is to be read
694  if ( fInfile == NULL || ::ferror(fInfile) != 0 || fStatus != kGood ) { NextFile(); if ( fStatus != kGood ) { cout << " Nothing to be read " << endl; return;} }
695 
696  // to get the next id record
697  bytesread += ::fread(fHeader->GetBuffer(),1,4,fInfile);
698 
699  while ( ::ferror(fInfile) == 0 || ::feof(fInfile) == 0 ) {
700 
701  fHeader->SetOffset(); (*fHeader) >> bsize ;
702 
703  if ( bsize == 40 ) { // this is a global record
704  if ( ReadGlobal() == kFALSE )
705  { cout << " GLOBAL record wrong " << endl; fStatus = kFail; break; }
706  else { bytesread += 44; nbglobal++; }
707 
708  // a new run has been read, so next record must be identified
709  bytesread += ::fread(fHeader->GetBuffer(),1,4,fInfile); fHeader->SetOffset(); (*fHeader) >> bsize ;
710  }
711  if ( bsize == 14 ) { // this is an id record
712  if ( ReadId() == kFALSE ) { cout << " ID record wrong " << endl; fStatus = kFail; break; }
713  else { bytesread += 18; nbid++; }
714 
715  bytesread += ::fread(fDataRecord->GetBuffer(),1,fId.NUM*8+8,fInfile);
716  fEventsRead[fCurrent]+=1.0; // a good event has just been read
717  }
718  else { cout << "Wrong size at position " << (::ftell(fInfile)) << " 14 expected instead of " << bsize << endl; fStatus = kFail; break;}
719 
720  bytesread += ::fread(fHeader->GetBuffer(),1,4,fInfile); // next id
721  } //
722 
723  cout << " # global record " << nbglobal << ", # id record " << nbid << ", bytes read " << bytesread << endl;
724  ShowCurrentConditions();
725 
726  // to re-start form the beginning
727  Rewind();
728 }
729 */
730 
EEndian
The adjectives big-endian and little-endian refer to which bytes are most significant in multi-byte d...
Definition: Memory.h:59
void ShowCurrentEvent(std::ostream &out=std::cout)
The show the content of the current event on the standard ouput.
Definition: EvapLMOF.cpp:256
TRandom * therand
Definition: EvapLMOF.cpp:33
void Rewind()
To restart the data stream from the beginning.
Definition: EvapLMOF.cpp:555
void ShowCurrentConditions(std::ostream &out=std::cout)
The current status is shown on the standard ouptut.
Definition: EvapLMOF.cpp:242
TLeaf * GetLeaf(const char *leafname="no")
To get a ROOT leaf corresponding to one of the variable.
Definition: EvapLMOF.cpp:633
UInt_t Size() const
it returns the maximum number of bytes in this buffer
Definition: Buffer.h:165
virtual void Reset()
Reset means set all elements to 0 and the current position is 0.
Definition: Buffer.cpp:78
void SetPath(const char *path="./")
set the directory where to find the input files
Definition: EvapLMOF.h:222
void Scan(UInt_t start=0, UInt_t end=10)
To scan events and show them on the standard output.
Definition: EvapLMOF.cpp:615
void NextFile()
switch to next file.
Definition: EvapLMOF.cpp:343
static Buffer * New(Memory::EEndian e, UInt_t s=32 *KBYTE)
copy n bytes from one buffer to another one
Definition: Buffer.cpp:68
UInt_t SetOffset(UInt_t off=0)
change the current position.
Definition: Buffer.cpp:88
ADF::LogMessage & endl(ADF::LogMessage &log)
static const Short_t MAXPARTICLES
Definition: EvapLMOF.h:101
static Short_t VERBOSE
Set verbosity level.
Definition: EvapLMOF.h:97
Bool_t NextEvent(UInt_t next=0)
To load the next event.
Definition: EvapLMOF.cpp:572
Char_t * GetBuffer()
Pointer to the underlying array of chars.
Definition: Buffer.h:164
bool IsStatus(Buffer::EStatus)
Definition: Buffer.h:156
bool IsBytes(Memory::EEndian) const
Definition: Buffer.h:162
static const Short_t MAXCASCADE
Definition: EvapLMOF.h:100