Millepede-II  V04-00-00
 All Classes Files Functions Variables Enumerator
Mille.cc
Go to the documentation of this file.
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 }