00001 #include "emcTracedFEM.h"
00002 #include "emcTracedValue.h"
00003 #include <iostream>
00004 #include <cassert>
00005 #include <ctime>
00006 #include <string>
00007 #include <cmath>
00008
00009 using std::string;
00010
00011 static string name = "emcTracedFEM" ;
00012 static string title = "Traced calibration data (base class)" ;
00013 static string classname = "emcTracedFEM" ;
00014
00015 namespace {
00016
00017 bool compare(Float_t x1, Float_t x2, float epsilon=1E-4)
00018 {
00019 if ( x1 == 0 && x2 == 0 )
00020 {
00021 return true;
00022 }
00023
00024 if ( std::abs((x1-x2)/x2) < epsilon )
00025 {
00026 return true;
00027 }
00028 else
00029 {
00030 return false;
00031 }
00032 }
00033 }
00034
00035
00036 emcTracedFEM::emcTracedFEM(int absPosition)
00037 : emcCalFEM(absPosition),
00038 fNItems(0),fCurrentItem(0),fCurrentPosition(0)
00039
00040 {
00041 NameIt(name,title,classname) ;
00042 }
00043
00044
00045 emcTracedFEM::emcTracedFEM(int absPosition,
00046 const PHTimeStamp& t1,
00047 const PHTimeStamp& t2)
00048 : emcCalFEM(absPosition,t1,t2),
00049 fNItems(0),fCurrentItem(0),fCurrentPosition(0)
00050 {
00051 NameIt(name,title,classname) ;
00052 }
00053
00054
00055 emcTracedFEM::emcTracedFEM(const emcTracedFEM& o)
00056 : emcCalFEM(o.AbsolutePosition())
00057 {
00058 o.Copy(*this) ;
00059 }
00060
00061
00062 emcTracedFEM&
00063 emcTracedFEM::operator=(const emcTracedFEM& o)
00064 {
00065 if ( this == &o ) return *this ;
00066
00067 Delete() ;
00068 o.Copy(*this) ;
00069 return *this ;
00070 }
00071
00072
00073 void
00074 emcTracedFEM::Copy(emcTracedFEM& o) const
00075 {
00076 emcCalFEM::Copy(o) ;
00077 o.fItems.resize(fItems.size(),0) ;
00078 size_t i ;
00079 int nitems = 0 ;
00080
00081 for (i=0;i<fItems.size();i++) {
00082 o.fItems[i] = new emcItemVector ;
00083 size_t j ;
00084 for (j=0;j<fItems[i]->size();j++) {
00085 emcTracedValue* tv = (*fItems[i])[j] ;
00086 o.fItems[i]->push_back(new emcTracedValue(tv->GetX(),
00087 tv->GetConstant(),
00088 tv->GetSlope(),
00089 tv->isConstant())) ;
00090 nitems++ ;
00091 }
00092 }
00093 o.fNItems = nitems ;
00094 assert(o.fNItems==fNItems) ;
00095 o.fCurrentItem = fCurrentItem ;
00096 o.fCurrentPosition = fCurrentPosition ;
00097 }
00098
00099
00100
00101 emcTracedFEM::~emcTracedFEM()
00102 {
00103 Delete() ;
00104 }
00105
00106
00107
00108 void emcTracedFEM::AddNewItem(int channel, emcTracedValue* item)
00109 {
00110
00111
00112
00113
00114
00115
00116
00117 assert (channel>=0 && channel<static_cast<int>(fItems.size())) ;
00118 assert(fItems[channel]!=0) ;
00119 emcItemVector& itemVector = *(fItems[channel]) ;
00120 emcTracedValue* currentitem ;
00121 size_t i ;
00122 bool inserted = false ;
00123
00124 for ( i = 0 ; i < itemVector.size() && !inserted ; i++ ) {
00125 currentitem = itemVector[i] ;
00126 assert(currentitem!=0) ;
00127 if ( currentitem->GetX() == item->GetX() ) {
00128
00129
00130 delete currentitem ;
00131 itemVector[i] = item ;
00132 inserted = true ;
00133 }
00134 }
00135 if (!inserted) {
00136 fNItems++ ;
00137 itemVector.push_back(item) ;
00138 }
00139 }
00140
00141
00142
00143 void emcTracedFEM::Delete(void)
00144 {
00145
00146 size_t i,j ;
00147
00148 for ( i = 0 ; i < fItems.size() ; i++ ) {
00149 assert(fItems[i]!=0) ;
00150 emcItemVector& itemVector = *(fItems[i]) ;
00151 for ( j = 0 ; j < itemVector.size() ; j++ ) {
00152 delete itemVector[j] ;
00153 itemVector[j] = 0 ;
00154 }
00155 delete fItems[i] ;
00156 fItems[i] = 0 ;
00157 }
00158
00159 fItems.clear() ;
00160 fNItems = 0 ;
00161 }
00162
00163
00164 void emcTracedFEM::FirstItem(int channel) const
00165 {
00166
00167 assert (channel>=0 && channel<static_cast<int>(fItems.size()));
00168 fCurrentItem = channel ;
00169 fCurrentPosition = 0 ;
00170 }
00171
00172
00173 size_t
00174 emcTracedFEM::GetNumberOfItems(int ichannel) const
00175 {
00176 if ( ichannel < 0 || ichannel >= static_cast<int>(fItems.size()) ) return 0;
00177 emcItemVector* vec = fItems[ichannel] ;
00178 if ( vec ) return vec->size() ;
00179 return 0 ;
00180 }
00181
00182
00183 emcTracedValue*
00184 emcTracedFEM::getTV(int ichannel, time_t absoluteX, size_t& thecase) const
00185 {
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 int x = static_cast<int>(absoluteX - GetXmin()) ;
00205
00206 emcItemVector* vec = fItems[ichannel] ;
00207 assert(vec!=0) ;
00208 emcItemVector& fTracedValues = *vec ;
00209
00210 if (fTracedValues.size()==0) { return 0 ; }
00211
00212 if ( x <= fTracedValues[0]->GetX() ) {
00213
00214
00215 thecase = 1 ;
00216 return fTracedValues[0] ;
00217 }
00218
00219 bool inside = false ;
00220 int i ;
00221 int n = static_cast<int>(fTracedValues.size()) ;
00222
00223 for ( i = 0 ; i < n-1 && !inside ; i++ ) {
00224 assert(fTracedValues[i]!=0) ;
00225 assert(fTracedValues[i+1]!=0) ;
00226 if ( x >= fTracedValues[i]->GetX() &&
00227 x < fTracedValues[i+1]->GetX() ) inside = true ;
00228 }
00229
00230 if (inside) {
00231 thecase = 2 ;
00232
00233
00234 assert(fTracedValues[i-1]!=0) ;
00235 return fTracedValues[i-1] ;
00236 }
00237
00238 int xrelmax = GetXmax()-GetXmin() ;
00239 assert(fTracedValues[n-1]!=0) ;
00240 if ( x>= fTracedValues[n-1]->GetX() && x<=xrelmax ) {
00241 thecase = 3 ;
00242
00243
00244 }
00245 else {
00246
00247 thecase = 4 ;
00248 }
00249 return fTracedValues[n-1] ;
00250 }
00251
00252
00253 float
00254 emcTracedFEM::getValueFast(int ichannel, time_t absoluteX) const
00255 {
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 size_t thecase ;
00277
00278 emcTracedValue* tv = getTV(ichannel, absoluteX, thecase) ;
00279
00280 float rv = 0.0 ;
00281
00282 if (!tv) thecase = 0 ;
00283
00284 int x = static_cast<int>(absoluteX - GetXmin()) ;
00285 int xrelmax = static_cast<int>(GetXmax()-GetXmin()) ;
00286
00287 switch (thecase) {
00288
00289 case 0 :
00290 rv = 1.0 ;
00291 break;
00292 case 1:
00293 rv = tv->GetConstant() ;
00294 break ;
00295 case 2:
00296 case 3:
00297 rv = tv->getValue(x) ;
00298 break ;
00299 case 4:
00300 rv = tv->getValue(xrelmax) ;
00301 break ;
00302 default:
00303 assert(0==1) ;
00304 break;
00305 }
00306
00307 return rv ;
00308 }
00309
00310
00311 bool
00312 emcTracedFEM::IsEqual(const emcCalFEM& obj) const
00313 {
00314 const emcTracedFEM* tfem = dynamic_cast<const emcTracedFEM*>(&obj) ;
00315 if (!tfem) return false ;
00316
00317 if ( size() != obj.size() ) return false ;
00318
00319 emcTracedValue* me;
00320 emcTracedValue* other;
00321
00322 for ( size_t ichannel = 0 ; ichannel < size() ; ichannel++) {
00323 FirstItem(ichannel) ;
00324 tfem->FirstItem(ichannel) ;
00325 while ( ( me = NextItem() ) ) {
00326 other = tfem->NextItem() ;
00327
00328
00329 if ( me->GetX() != other->GetX() )
00330 {
00331 return false ;
00332 }
00333 if ( !compare(me->GetConstant(),other->GetConstant()))
00334 {
00335 return false ;
00336 }
00337 if ( !compare(me->GetSlope(),other->GetSlope()))
00338 {
00339 return false ;
00340 }
00341 if ( me->isConstant() != other->isConstant())
00342 {
00343 return false ;
00344 }
00345 }
00346 }
00347
00348 return true ;
00349 }
00350
00351
00352 emcTracedValue*
00353 emcTracedFEM::LastItem(int channel) const
00354 {
00355 if ( channel >= static_cast<int>( fItems.size() ) ||
00356 channel < 0 ) {
00357 return 0 ;
00358 }
00359
00360 emcTracedValue* tv = 0 ;
00361 emcItemVector* vec = fItems[channel] ;
00362
00363 if (vec) {
00364 int i = vec->size()-1 ;
00365 if (i>=0) {
00366 tv = (*vec)[i] ;
00367 }
00368 }
00369 return tv ;
00370 }
00371
00372
00373 emcTracedValue* emcTracedFEM::NextItem(void) const
00374 {
00375
00376 emcTracedValue* rv = 0 ;
00377
00378 if (fCurrentItem<fItems.size()) {
00379 emcItemVector* vec = fItems[fCurrentItem] ;
00380 assert(vec!=0) ;
00381 if (fCurrentPosition<vec->size()) {
00382 rv = (*vec)[fCurrentPosition] ;
00383 fCurrentPosition++ ;
00384 }
00385 }
00386 return rv ;
00387 }
00388
00389
00390 std::ostream&
00391 emcTracedFEM::Print(std::ostream& out, int level) const
00392 {
00393 emcCalFEM::Print(out,level) ;
00394
00395 if (level) {
00396 out << "xmin=" << GetXmin() << " xmax=" << GetXmax() << std::endl ;
00397 for ( size_t i = 0 ; i < fItems.size() ; i++) {
00398 emcItemVector* vec = fItems[i] ;
00399 if (vec) {
00400 for (size_t j = 0; j < vec->size() ; j++) {
00401 out << i << " " << *((*vec)[j]) ;
00402 }
00403 }
00404 }
00405 }
00406 return out ;
00407 }
00408
00409
00410 void
00411 emcTracedFEM::RemoveLastItems(void)
00412 {
00413
00414
00415 for (size_t i = 0 ; i < fItems.size() ; ++i) {
00416 emcItemVector* vec = fItems[i] ;
00417 if (vec) {
00418 emcTracedValue* last = vec->back() ;
00419 delete last ;
00420 last = 0 ;
00421 vec->pop_back() ;
00422 --fNItems ;
00423 }
00424 }
00425 }
00426
00427
00428 void emcTracedFEM::Reset(void)
00429 {
00430 Delete() ;
00431 SetXmin(0) ;
00432 SetXmax(0) ;
00433 }
00434
00435
00436 void emcTracedFEM::SetNumberOfChannels(int number_of_channels)
00437 {
00438 assert (number_of_channels>=0) ;
00439
00440 Delete() ;
00441 fItems.resize(number_of_channels) ;
00442
00443 for( size_t i = 0 ; i < fItems.size() ; i++ ) {
00444 fItems[i] = new emcItemVector() ;
00445 }
00446 }
00447
00448
00449 void emcTracedFEM::writeDataToFile(FILE* fp) const
00450 {
00451 time_t tics = GetStartValTime().getTics();
00452 char timeString[25];
00453 timeString[24] = '\0';
00454 strncpy(timeString, ctime(&tics), 24);
00455 fprintf(fp,"%s\n",timeString) ;
00456
00457 size_t i,j ;
00458 int item = 0 ;
00459
00460 for (i=0;i<fItems.size();i++) {
00461 assert(fItems[i]!=0) ;
00462 emcItemVector& itemVector = *(fItems[i]) ;
00463 for (j=0;j<itemVector.size();j++) {
00464 fprintf(fp," %5d", item) ;
00465 itemVector[j]->writeData(fp) ;
00466 fprintf(fp,"\n") ;
00467 }
00468 item++ ;
00469 }
00470 fprintf(fp,"144 %ld 0 0\n",GetXmax());
00471 fprintf(fp,"145 %ld 0 0\n",GetXmin());
00472 }