![]() |
Millepede-II
V04-00-00
|
00001 00012 #include "Mille.h" 00013 00014 #include <fstream> 00015 #include <iostream> 00016 00017 //___________________________________________________________________________ 00018 00020 00025 Mille::Mille(const char *outFileName, bool asBinary, bool writeZero) : 00026 myOutFile(outFileName, (asBinary ? (std::ios::binary | std::ios::out) : std::ios::out)), 00027 myAsBinary(asBinary), myWriteZero(writeZero), myBufferPos(-1), myHasSpecial(false) 00028 { 00029 // Instead myBufferPos(-1), myHasSpecial(false) and the following two lines 00030 // we could call newSet() and kill()... 00031 myBufferInt[0] = 0; 00032 myBufferFloat[0] = 0.; 00033 00034 if (!myOutFile.is_open()) { 00035 std::cerr << "Mille::Mille: Could not open " << outFileName 00036 << " as output file." << std::endl; 00037 } 00038 } 00039 00040 //___________________________________________________________________________ 00042 Mille::~Mille() 00043 { 00044 myOutFile.close(); 00045 } 00046 00047 //___________________________________________________________________________ 00049 00058 void Mille::mille(int NLC, const float *derLc, 00059 int NGL, const float *derGl, const int *label, 00060 float rMeas, float sigma) 00061 { 00062 if (sigma <= 0.) return; 00063 if (myBufferPos == -1) this->newSet(); // start, e.g. new track 00064 if (!this->checkBufferSize(NLC, NGL)) return; 00065 00066 // first store measurement 00067 ++myBufferPos; 00068 myBufferFloat[myBufferPos] = rMeas; 00069 myBufferInt [myBufferPos] = 0; 00070 00071 // store local derivatives and local 'lables' 1,...,NLC 00072 for (int i = 0; i < NLC; ++i) { 00073 if (derLc[i] || myWriteZero) { // by default store only non-zero derivatives 00074 ++myBufferPos; 00075 myBufferFloat[myBufferPos] = derLc[i]; // local derivatives 00076 myBufferInt [myBufferPos] = i+1; // index of local parameter 00077 } 00078 } 00079 00080 // store uncertainty of measurement in between locals and globals 00081 ++myBufferPos; 00082 myBufferFloat[myBufferPos] = sigma; 00083 myBufferInt [myBufferPos] = 0; 00084 00085 // store global derivatives and their labels 00086 for (int i = 0; i < NGL; ++i) { 00087 if (derGl[i] || myWriteZero) { // by default store only non-zero derivatives 00088 if ((label[i] > 0 || myWriteZero) && label[i] <= myMaxLabel) { // and for valid labels 00089 ++myBufferPos; 00090 myBufferFloat[myBufferPos] = derGl[i]; // global derivatives 00091 myBufferInt [myBufferPos] = label[i]; // index of global parameter 00092 } else { 00093 std::cerr << "Mille::mille: Invalid label " << label[i] 00094 << " <= 0 or > " << myMaxLabel << std::endl; 00095 } 00096 } 00097 } 00098 } 00099 00100 //___________________________________________________________________________ 00102 00107 void Mille::special(int nSpecial, const float *floatings, const int *integers) 00108 { 00109 if (nSpecial == 0) return; 00110 if (myBufferPos == -1) this->newSet(); // start, e.g. new track 00111 if (myHasSpecial) { 00112 std::cerr << "Mille::special: Special values already stored for this record." 00113 << std::endl; 00114 return; 00115 } 00116 if (!this->checkBufferSize(nSpecial, 0)) return; 00117 myHasSpecial = true; // after newSet() (Note: MILLSP sets to buffer position...) 00118 00119 // myBufferFloat[.] | myBufferInt[.] 00120 // ------------------------------------ 00121 // 0.0 | 0 00122 // -float(nSpecial) | 0 00123 // The above indicates special data, following are nSpecial floating and nSpecial integer data. 00124 00125 ++myBufferPos; // zero pair 00126 myBufferFloat[myBufferPos] = 0.; 00127 myBufferInt [myBufferPos] = 0; 00128 00129 ++myBufferPos; // nSpecial and zero 00130 myBufferFloat[myBufferPos] = -nSpecial; // automatic conversion to float 00131 myBufferInt [myBufferPos] = 0; 00132 00133 for (int i = 0; i < nSpecial; ++i) { 00134 ++myBufferPos; 00135 myBufferFloat[myBufferPos] = floatings[i]; 00136 myBufferInt [myBufferPos] = integers[i]; 00137 } 00138 } 00139 00140 //___________________________________________________________________________ 00142 void Mille::kill() 00143 { 00144 myBufferPos = -1; 00145 } 00146 00147 //___________________________________________________________________________ 00149 void Mille::end() 00150 { 00151 if (myBufferPos > 0) { // only if anything stored... 00152 const int numWordsToWrite = (myBufferPos + 1)*2; 00153 00154 if (myAsBinary) { 00155 myOutFile.write(reinterpret_cast<const char*>(&numWordsToWrite), 00156 sizeof(numWordsToWrite)); 00157 myOutFile.write(reinterpret_cast<char*>(myBufferFloat), 00158 (myBufferPos+1) * sizeof(myBufferFloat[0])); 00159 myOutFile.write(reinterpret_cast<char*>(myBufferInt), 00160 (myBufferPos+1) * sizeof(myBufferInt[0])); 00161 } else { 00162 myOutFile << numWordsToWrite << "\n"; 00163 for (int i = 0; i < myBufferPos+1; ++i) { 00164 myOutFile << myBufferFloat[i] << " "; 00165 } 00166 myOutFile << "\n"; 00167 00168 for (int i = 0; i < myBufferPos+1; ++i) { 00169 myOutFile << myBufferInt[i] << " "; 00170 } 00171 myOutFile << "\n"; 00172 } 00173 } 00174 myBufferPos = -1; // reset buffer for next set of derivatives 00175 } 00176 00177 //___________________________________________________________________________ 00179 void Mille::newSet() 00180 { 00181 myBufferPos = 0; 00182 myHasSpecial = false; 00183 myBufferFloat[0] = 0.0; 00184 myBufferInt [0] = 0; // position 0 used as error counter 00185 } 00186 00187 //___________________________________________________________________________ 00189 00194 bool Mille::checkBufferSize(int nLocal, int nGlobal) 00195 { 00196 if (myBufferPos + nLocal + nGlobal + 2 >= myBufferSize) { 00197 ++(myBufferInt[0]); // increase error count 00198 std::cerr << "Mille::checkBufferSize: Buffer too short (" 00199 << myBufferSize << ")," 00200 << "\n need space for nLocal (" << nLocal<< ")" 00201 << "/nGlobal (" << nGlobal << ") local/global derivatives, " 00202 << myBufferPos + 1 << " already stored!" 00203 << std::endl; 00204 return false; 00205 } else { 00206 return true; 00207 } 00208 }