Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MilleFieldOn/Mille.cc
Go to the documentation of this file.
1 /**
2  * \file
3  * Create Millepede-II C-binary record.
4  *
5  * \author : Gero Flucke
6  * date : October 2006
7  * $Revision: 1.3 $
8  * $Date: 2007/04/16 17:47:38 $
9  * (last update by $Author: flucke $)
10  */
11 
12 #include "Mille.h"
13 
14 #include <fstream>
15 #include <iostream>
16 
17 //___________________________________________________________________________
18 
19 /// Opens outFileName (by default as binary file).
20 /**
21  * \param[in] outFileName file name
22  * \param[in] asBinary flag for binary
23  * \param[in] writeZero flag for keeping of zeros
24  */
25 Mille::Mille(const char *outFileName, bool asBinary, bool writeZero) :
26  myOutFile(outFileName, (asBinary ? (std::ios::binary | std::ios::out) : std::ios::out)),
27  myAsBinary(asBinary), myWriteZero(writeZero), myBufferPos(-1), myHasSpecial(false)
28 {
29  // Instead myBufferPos(-1), myHasSpecial(false) and the following two lines
30  // we could call newSet() and kill()...
31  myBufferInt[0] = 0;
32  myBufferFloat[0] = 0.;
33 
34  if (!myOutFile.is_open()) {
35  std::cerr << "Mille::Mille: Could not open " << outFileName
36  << " as output file." << std::endl;
37  }
38 }
39 
40 //___________________________________________________________________________
41 /// Closes file.
43 {
44  myOutFile.close();
45 }
46 
47 //___________________________________________________________________________
48 /// Add measurement to buffer.
49 /**
50  * \param[in] NLC number of local derivatives
51  * \param[in] derLc local derivatives
52  * \param[in] NGL number of global derivatives
53  * \param[in] derGl global derivatives
54  * \param[in] label global labels
55  * \param[in] rMeas measurement (residuum)
56  * \param[in] sigma error
57  */
58 void Mille::mille(int NLC, const float *derLc,
59  int NGL, const float *derGl, const int *label,
60  float rMeas, float sigma)
61 {
62  if (sigma <= 0.) return;
63  if (myBufferPos == -1) this->newSet(); // start, e.g. new track
64  if (!this->checkBufferSize(NLC, NGL)) return;
65 
66  // first store measurement
67  ++myBufferPos;
68  myBufferFloat[myBufferPos] = rMeas;
70 
71  // store local derivatives and local 'lables' 1,...,NLC
72  for (int i = 0; i < NLC; ++i) {
73  if (derLc[i] || myWriteZero) { // by default store only non-zero derivatives
74  ++myBufferPos;
75  myBufferFloat[myBufferPos] = derLc[i]; // local derivatives
76  myBufferInt [myBufferPos] = i+1; // index of local parameter
77  }
78  }
79 
80  // store uncertainty of measurement in between locals and globals
81  ++myBufferPos;
84 
85  // store global derivatives and their labels
86  for (int i = 0; i < NGL; ++i) {
87  if (derGl[i] || myWriteZero) { // by default store only non-zero derivatives
88  if ((label[i] > 0 || myWriteZero) && label[i] <= myMaxLabel) { // and for valid labels
89  ++myBufferPos;
90  myBufferFloat[myBufferPos] = derGl[i]; // global derivatives
91  myBufferInt [myBufferPos] = label[i]; // index of global parameter
92  } else {
93  std::cerr << "Mille::mille: Invalid label " << label[i]
94  << " <= 0 or > " << myMaxLabel << std::endl;
95  }
96  }
97  }
98 }
99 
100 //___________________________________________________________________________
101 /// Add special data to buffer.
102 /**
103  * \param[in] nSpecial number of floats/ints
104  * \param[in] floatings floats
105  * \param[in] integers ints
106  */
107 void Mille::special(int nSpecial, const float *floatings, const int *integers)
108 {
109  if (nSpecial == 0) return;
110  if (myBufferPos == -1) this->newSet(); // start, e.g. new track
111  if (myHasSpecial) {
112  std::cerr << "Mille::special: Special values already stored for this record."
113  << std::endl;
114  return;
115  }
116  if (!this->checkBufferSize(nSpecial, 0)) return;
117  myHasSpecial = true; // after newSet() (Note: MILLSP sets to buffer position...)
118 
119  // myBufferFloat[.] | myBufferInt[.]
120  // ------------------------------------
121  // 0.0 | 0
122  // -float(nSpecial) | 0
123  // The above indicates special data, following are nSpecial floating and nSpecial integer data.
124 
125  ++myBufferPos; // zero pair
127  myBufferInt [myBufferPos] = 0;
128 
129  ++myBufferPos; // nSpecial and zero
130  myBufferFloat[myBufferPos] = -nSpecial; // automatic conversion to float
131  myBufferInt [myBufferPos] = 0;
132 
133  for (int i = 0; i < nSpecial; ++i) {
134  ++myBufferPos;
135  myBufferFloat[myBufferPos] = floatings[i];
136  myBufferInt [myBufferPos] = integers[i];
137  }
138 }
139 
140 //___________________________________________________________________________
141 /// Reset buffers, i.e. kill derivatives accumulated for current set.
142 void Mille::kill()
143 {
144  myBufferPos = -1;
145 }
146 
147 //___________________________________________________________________________
148 /// Write buffer (set of derivatives with same local parameters) to file.
149 void Mille::end()
150 {
151  if (myBufferPos > 0) { // only if anything stored...
152  const int numWordsToWrite = (myBufferPos + 1)*2;
153 
154  if (myAsBinary) {
155  myOutFile.write(reinterpret_cast<const char*>(&numWordsToWrite),
156  sizeof(numWordsToWrite));
157  myOutFile.write(reinterpret_cast<char*>(myBufferFloat),
158  (myBufferPos+1) * sizeof(myBufferFloat[0]));
159  myOutFile.write(reinterpret_cast<char*>(myBufferInt),
160  (myBufferPos+1) * sizeof(myBufferInt[0]));
161  } else {
162  myOutFile << numWordsToWrite << "\n";
163  for (int i = 0; i < myBufferPos+1; ++i) {
164  myOutFile << myBufferFloat[i] << " ";
165  }
166  myOutFile << "\n";
167 
168  for (int i = 0; i < myBufferPos+1; ++i) {
169  myOutFile << myBufferInt[i] << " ";
170  }
171  myOutFile << "\n";
172  }
173  }
174  myBufferPos = -1; // reset buffer for next set of derivatives
175 }
176 
177 //___________________________________________________________________________
178 /// Initialize for new set of locals, e.g. new track.
179 void Mille::newSet()
180 {
181  myBufferPos = 0;
182  myHasSpecial = false;
183  myBufferFloat[0] = 0.0;
184  myBufferInt [0] = 0; // position 0 used as error counter
185 }
186 
187 //___________________________________________________________________________
188 /// Enough space for next nLocal + nGlobal derivatives incl. measurement?
189 /**
190  * \param[in] nLocal number of local derivatives
191  * \param[in] nGlobal number of global derivatives
192  * \return true if sufficient space available (else false)
193  */
194 bool Mille::checkBufferSize(int nLocal, int nGlobal)
195 {
196  if (myBufferPos + nLocal + nGlobal + 2 >= myBufferSize) {
197  ++(myBufferInt[0]); // increase error count
198  std::cerr << "Mille::checkBufferSize: Buffer too short ("
199  << myBufferSize << "),"
200  << "\n need space for nLocal (" << nLocal<< ")"
201  << "/nGlobal (" << nGlobal << ") local/global derivatives, "
202  << myBufferPos + 1 << " already stored!"
203  << std::endl;
204  return false;
205  } else {
206  return true;
207  }
208 }
~Mille()
Closes file.
bool myHasSpecial
if true, special(..) already called for this record largest label allowed: 2^31 ...
void mille(int NLC, const float *derLc, int NGL, const float *derGl, const int *label, float rMeas, float sigma)
Add measurement to buffer.
bool myAsBinary
if false output as text
std::ofstream myOutFile
C-binary for output.
float myBufferFloat[myBufferSize]
to collect derivatives etc.
void special(int nSpecial, const float *floatings, const int *integers)
Add special data to buffer.
void kill()
Reset buffers, i.e. kill derivatives accumulated for current set.
bool myWriteZero
if true also write out derivatives/labels ==0 buffer size for ints and floa...
Double_t sigma[NCHANNELS]
Definition: st_tw_resols.C:37
void end()
Write buffer (set of derivatives with same local parameters) to file.
int myBufferInt[myBufferSize]
to collect labels etc.
int myBufferPos
position in buffer
void newSet()
Initialize for new set of locals, e.g. new track.
bool checkBufferSize(int nLocal, int nGlobal)
Enough space for next nLocal + nGlobal derivatives incl. measurement?
Mille(const char *outFileName, bool asBinary=true, bool writeZero=false)
Opens outFileName (by default as binary file).