CMS 3D CMS Logo

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