FairRoot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Mille.cc
Go to the documentation of this file.
1 
10 #include "Mille.h"
11 
12 #include <fstream>
13 #include <iostream>
14 
15 Mille::Mille(const char *outFileName, bool asBinary, bool writeZero) :
16  myOutFile(outFileName, (asBinary ? (std::ios::binary | std::ios::out) : std::ios::out)),
17  myAsBinary(asBinary), myWriteZero(writeZero), myBufferPos(-1), myHasSpecial(false)
18 {
19  // opens outFileName, by default as binary file
20 
21  // Instead myBufferPos(-1), myHasSpecial(false) and the following two lines
22  // we could call newSet() and kill()...
23  myBufferInt[0] = 0;
24  myBufferFloat[0] = 0.;
25 
26  if (!myOutFile.is_open()) {
27  std::cerr << "Mille::Mille: Could not open " << outFileName
28  << " as output file." << std::endl;
29  }
30 }
31 
33 {
34  // closes file
35  myOutFile.close();
36 }
37 
38 void Mille::mille(int NLC, const float *derLc,
39  int NGL, const float *derGl, const int *label,
40  float rMeas, float sigma)
41 {
42  if (sigma <= 0.) return;
43  if (myBufferPos == -1) this->newSet(); // start, e.g. new track
44  if (!this->checkBufferSize(NLC, NGL)) return;
45 
46  // first store measurement
47  ++myBufferPos;
48  myBufferFloat[myBufferPos] = rMeas;
49  myBufferInt [myBufferPos] = 0;
50 
51  // store local derivatives and local 'lables' 1,...,NLC
52  for (int i = 0; i < NLC; ++i) {
53  if (derLc[i] || myWriteZero) { // by default store only non-zero derivatives
54  ++myBufferPos;
55  myBufferFloat[myBufferPos] = derLc[i]; // local derivatives
56  myBufferInt [myBufferPos] = i+1; // index of local parameter
57  }
58  }
59 
60  // store uncertainty of measurement in between locals and globals
61  ++myBufferPos;
62  myBufferFloat[myBufferPos] = sigma;
63  myBufferInt [myBufferPos] = 0;
64 
65  // store global derivatives and their lables
66  for (int i = 0; i < NGL; ++i) {
67  if (derGl[i] || myWriteZero) { // by default store only non-zero derivatives
68  // label[i] is always smaller than myMaxLabel, because myMaxLabel is set to the largest possible value allowed by c++
69  // coverity[result_independent_of_operands]
70  if ((label[i] > 0 || myWriteZero) && label[i] <= myMaxLabel) { // and for valid labels
71  ++myBufferPos;
72  myBufferFloat[myBufferPos] = derGl[i]; // global derivatives
73  myBufferInt [myBufferPos] = label[i]; // index of global parameter
74  } else {
75  std::cerr << "Mille::mille: Invalid label " << label[i]
76  << " <= 0 or > " << myMaxLabel << std::endl;
77  }
78  }
79  }
80 }
81 
82 void Mille::special(int nSpecial, const float *floatings, const int *integers)
83 {
84  if (nSpecial == 0) return;
85  if (myBufferPos == -1) this->newSet(); // start, e.g. new track
86  if (myHasSpecial) {
87  std::cerr << "Mille::special: Special values already stored for this record."
88  << std::endl;
89  return;
90  }
91  if (!this->checkBufferSize(nSpecial, 0)) return;
92  myHasSpecial = true; // after newSet() (Note: MILLSP sets to buffer position...)
93 
94  // myBufferFloat[.] | myBufferInt[.]
95  // ------------------------------------
96  // 0.0 | 0
97  // -float(nSpecial) | 0
98  // The above indicates special data, following are nSpecial floating and nSpecial integer data.
99 
100  ++myBufferPos; // zero pair
101  myBufferFloat[myBufferPos] = 0.;
102  myBufferInt [myBufferPos] = 0;
103 
104  ++myBufferPos; // nSpecial and zero
105  myBufferFloat[myBufferPos] = -nSpecial; // automatic conversion to float
106  myBufferInt [myBufferPos] = 0;
107 
108  for (int i = 0; i < nSpecial; ++i) {
109  ++myBufferPos;
110  myBufferFloat[myBufferPos] = floatings[i];
111  myBufferInt [myBufferPos] = integers[i];
112  }
113 }
114 
116 {
117  // reset buffers, i.e. kill derivatives accumulated for current set
118  myBufferPos = -1;
119 }
120 
122 {
123  // write set of derivatives with same local parameters to file
124  if (myBufferPos > 0) { // only if anything stored...
125  const int numWordsToWrite = (myBufferPos + 1)*2;
126 
127  if (myAsBinary) {
128  myOutFile.write(reinterpret_cast<const char*>(&numWordsToWrite),
129  sizeof(numWordsToWrite));
130  myOutFile.write(reinterpret_cast<char*>(myBufferFloat),
131  (myBufferPos+1) * sizeof(myBufferFloat[0]));
132  myOutFile.write(reinterpret_cast<char*>(myBufferInt),
133  (myBufferPos+1) * sizeof(myBufferInt[0]));
134  } else {
135 
136  myOutFile << numWordsToWrite << "\n";
137  for (int i = 0; i < myBufferPos+1; ++i) {
138  myOutFile << myBufferFloat[i] << " ";
139  }
140  myOutFile << "\n";
141 
142  for (int i = 0; i < myBufferPos+1; ++i) {
143  myOutFile << myBufferInt[i] << " ";
144  }
145  myOutFile << "\n";
146 
147  /*
148  std::cout << numWordsToWrite << "\n";
149  for (int i = 0; i < myBufferPos+1; ++i) {
150  std::cout << myBufferFloat[i] << " ";
151  }
152  std::cout << "\n";
153 
154  for (int i = 0; i < myBufferPos+1; ++i) {
155  std::cout << myBufferInt[i] << " ";
156  }
157  std::cout << "\n";
158  */
159  }
160  }
161  myBufferPos = -1; // reset buffer for next set of derivatives
162 }
163 
164 void Mille::newSet()
165 {
166  // initilise for new set of locals, e.g. new track
167  myBufferPos = 0;
168  myHasSpecial = false;
169  myBufferFloat[0] = 0.0;
170  myBufferInt [0] = 0; // position 0 used as error counter
171 }
172 
173 bool Mille::checkBufferSize(int nLocal, int nGlobal)
174 {
175  // enough space for next nLocal + nGlobal derivatives incl. measurement?
176 
177  if (myBufferPos + nLocal + nGlobal + 2 >= myBufferSize) {
178  ++(myBufferInt[0]); // increase error count
179  std::cerr << "Mille::checkBufferSize: Buffer too short ("
180  << myBufferSize << "),"
181  << "\n need space for nLocal (" << nLocal<< ")"
182  << "/nGlobal (" << nGlobal << ") local/global derivatives, "
183  << myBufferPos + 1 << " already stored!"
184  << std::endl;
185  return false;
186  } else {
187  return true;
188  }
189 }
Mille(const char *outFileName, bool asBinary=true, bool writeZero=false)
Definition: Mille.cc:15
void end()
Definition: Mille.cc:121
void mille(int NLC, const float *derLc, int NGL, const float *derGl, const int *label, float rMeas, float sigma)
Definition: Mille.cc:38
void kill()
Definition: Mille.cc:115
~Mille()
Definition: Mille.cc:32
void special(int nSpecial, const float *floatings, const int *integers)
Definition: Mille.cc:82