Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Mille.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Mille.cc
1 
32 #include "Mille.h"
33 
34 #include <fstream>
35 #include <iostream>
36 
37 //___________________________________________________________________________
38 
40 
45 Mille::Mille(const char *outFileName, bool asBinary, bool writeZero) :
46  myOutFile(outFileName, (asBinary ? (std::ios::binary | std::ios::out) : std::ios::out)),
47  myAsBinary(asBinary), myWriteZero(writeZero), myBufferPos(-1), myHasSpecial(false)
48 {
49  // Instead myBufferPos(-1), myHasSpecial(false) and the following two lines
50  // we could call newSet() and kill()...
51  myBufferInt[0] = 0;
52  myBufferFloat[0] = 0.;
53 
54  if (!myOutFile.is_open()) {
55  std::cerr << "Mille::Mille: Could not open " << outFileName
56  << " as output file." << std::endl;
57  }
58 }
59 
60 //___________________________________________________________________________
63 {
64  myOutFile.close();
65 }
66 
67 //___________________________________________________________________________
69 
78 void Mille::mille(int NLC, const float *derLc,
79  int NGL, const float *derGl, const int *label,
80  float rMeas, float sigma)
81 {
82  if (sigma <= 0.) return;
83  if (myBufferPos == -1) this->newSet(); // start, e.g. new track
84  if (!this->checkBufferSize(NLC, NGL)) return;
85 
86  // first store measurement
87  ++myBufferPos;
88  myBufferFloat[myBufferPos] = rMeas;
90 
91  // store local derivatives and local 'lables' 1,...,NLC
92  for (int i = 0; i < NLC; ++i) {
93  if (derLc[i] || myWriteZero) { // by default store only non-zero derivatives
94  ++myBufferPos;
95  myBufferFloat[myBufferPos] = derLc[i]; // local derivatives
96  myBufferInt [myBufferPos] = i+1; // index of local parameter
97  }
98  }
99 
100  // store uncertainty of measurement in between locals and globals
101  ++myBufferPos;
103  myBufferInt [myBufferPos] = 0;
104 
105  // store global derivatives and their labels
106  for (int i = 0; i < NGL; ++i) {
107  if (derGl[i] || myWriteZero) { // by default store only non-zero derivatives
108  if ((label[i] > 0 || myWriteZero) && label[i] <= myMaxLabel) { // and for valid labels
109  ++myBufferPos;
110  myBufferFloat[myBufferPos] = derGl[i]; // global derivatives
111  myBufferInt [myBufferPos] = label[i]; // index of global parameter
112  } else {
113  std::cerr << "Mille::mille: Invalid label " << label[i]
114  << " <= 0 or > " << myMaxLabel << std::endl;
115  }
116  }
117  }
118 }
119 
120 //___________________________________________________________________________
122 
127 void Mille::special(int nSpecial, const float *floatings, const int *integers)
128 {
129  if (nSpecial == 0) return;
130  if (myBufferPos == -1) this->newSet(); // start, e.g. new track
131  if (myHasSpecial) {
132  std::cerr << "Mille::special: Special values already stored for this record."
133  << std::endl;
134  return;
135  }
136  if (!this->checkBufferSize(nSpecial, 0)) return;
137  myHasSpecial = true; // after newSet() (Note: MILLSP sets to buffer position...)
138 
139  // myBufferFloat[.] | myBufferInt[.]
140  // ------------------------------------
141  // 0.0 | 0
142  // -float(nSpecial) | 0
143  // The above indicates special data, following are nSpecial floating and nSpecial integer data.
144 
145  ++myBufferPos; // zero pair
147  myBufferInt [myBufferPos] = 0;
148 
149  ++myBufferPos; // nSpecial and zero
150  myBufferFloat[myBufferPos] = -nSpecial; // automatic conversion to float
151  myBufferInt [myBufferPos] = 0;
152 
153  for (int i = 0; i < nSpecial; ++i) {
154  ++myBufferPos;
155  myBufferFloat[myBufferPos] = floatings[i];
156  myBufferInt [myBufferPos] = integers[i];
157  }
158 }
159 
160 //___________________________________________________________________________
163 {
164  myBufferPos = -1;
165 }
166 
167 //___________________________________________________________________________
170 {
171  // std:: cout << " Mille::end() called with myBufferPos " << myBufferPos << std::endl;
172 
173  if (myBufferPos > 0) { // only if anything stored...
174  const int numWordsToWrite = (myBufferPos + 1)*2;
175 
176  if (myAsBinary) {
177  myOutFile.write(reinterpret_cast<const char*>(&numWordsToWrite),
178  sizeof(numWordsToWrite));
179  myOutFile.write(reinterpret_cast<char*>(myBufferFloat),
180  (myBufferPos+1) * sizeof(myBufferFloat[0]));
181  myOutFile.write(reinterpret_cast<char*>(myBufferInt),
182  (myBufferPos+1) * sizeof(myBufferInt[0]));
183  } else {
184  myOutFile << numWordsToWrite << "\n";
185  for (int i = 0; i < myBufferPos+1; ++i) {
186  myOutFile << myBufferFloat[i] << " ";
187  }
188  myOutFile << "\n";
189 
190  for (int i = 0; i < myBufferPos+1; ++i) {
191  myOutFile << myBufferInt[i] << " ";
192  }
193  myOutFile << "\n";
194  }
195  }
196  myBufferPos = -1; // reset buffer for next set of derivatives
197 
198  // std:: cout << " Mille::end() finished with myBufferPos " << myBufferPos << std::endl;
199 }
200 
201 //___________________________________________________________________________
204 {
205  myBufferPos = 0;
206  myHasSpecial = false;
207  myBufferFloat[0] = 0.0;
208  myBufferInt [0] = 0; // position 0 used as error counter
209 }
210 
211 //___________________________________________________________________________
213 
218 bool Mille::checkBufferSize(int nLocal, int nGlobal)
219 {
220  if (myBufferPos + nLocal + nGlobal + 2 >= myBufferSize) {
221  ++(myBufferInt[0]); // increase error count
222  std::cerr << "Mille::checkBufferSize: Buffer too short ("
223  << myBufferSize << "),"
224  << "\n need space for nLocal (" << nLocal<< ")"
225  << "/nGlobal (" << nGlobal << ") local/global derivatives, "
226  << myBufferPos + 1 << " already stored!"
227  << std::endl;
228  return false;
229  } else {
230  return true;
231  }
232 }