AraEvent/AraEventCalibrator.cxx
00001 00002 00003 00004 00005 00006 00007 00008 00009 #include "AraEventCalibrator.h" 00010 #include "UsefulAraEvent.h" 00011 #include "AraGeomTool.h" 00012 #include "TMath.h" 00013 #include "TGraph.h" 00014 #include <iostream> 00015 #include <fstream> 00016 #include <cstring> 00017 #include <zlib.h> 00018 #include <cstdlib> 00019 00020 00021 Bool_t AraCalType::hasCableDelays(AraCalType::AraCalType_t calType) 00022 { 00023 if(calType==kFirstCalibPlusCables || calType==kSecondCalibPlusCables) 00024 return kTRUE; 00025 return kFALSE; 00026 } 00027 00028 Bool_t AraCalType::hasInterleaveCalib(AraCalType::AraCalType_t calType) 00029 { 00030 if(calType==kFirstCalibPlusCables || calType==kSecondCalibPlusCables || 00031 calType==kFirstCalib || calType==kSecondCalib) 00032 return kTRUE; 00033 return kFALSE; 00034 } 00035 00036 Bool_t AraCalType::hasBinWidthCalib(AraCalType::AraCalType_t calType) 00037 { 00038 if(calType==kFirstCalibPlusCables || calType==kSecondCalibPlusCables || 00039 calType==kFirstCalib || calType==kSecondCalib) 00040 return kTRUE; 00041 return kFALSE; 00042 } 00043 00044 00045 Bool_t AraCalType::hasClockAlignment(AraCalType::AraCalType_t calType) 00046 { 00047 if(calType==kSecondCalibPlusCables || 00048 calType==kSecondCalib) 00049 return kTRUE; 00050 return kFALSE; 00051 } 00052 00053 ClassImp(AraEventCalibrator); 00054 00055 AraEventCalibrator * AraEventCalibrator::fgInstance=0; 00056 00057 00058 AraEventCalibrator::AraEventCalibrator() 00059 { 00060 gotPedFile=0; 00061 loadCalib(); 00062 //Default Constructor 00063 } 00064 00065 AraEventCalibrator::~AraEventCalibrator() { 00066 //Default Destructor 00067 } 00068 00069 //______________________________________________________________________________ 00070 AraEventCalibrator* AraEventCalibrator::Instance() 00071 { 00072 //static function 00073 if(fgInstance) 00074 return fgInstance; 00075 00076 fgInstance = new AraEventCalibrator(); 00077 return fgInstance; 00078 } 00079 00080 00081 void AraEventCalibrator::setPedFile(char fileName[]) 00082 { 00083 strncpy(pedFile,fileName,FILENAME_MAX); 00084 gotPedFile=1; 00085 loadPedestals(); 00086 } 00087 00088 void AraEventCalibrator::loadPedestals() 00089 { 00090 if(!gotPedFile) { 00091 char *pedFileEnv = getenv( "ARA_PEDESTAL_FILE" ); 00092 if ( pedFileEnv == NULL ) { 00093 char calibDir[FILENAME_MAX]; 00094 char *calibEnv=getenv("ARA_CALIB_DIR"); 00095 if(!calibEnv) { 00096 char *utilEnv=getenv("ARA_UTIL_INSTALL_DIR"); 00097 if(!utilEnv) { 00098 sprintf(calibDir,"calib"); 00099 fprintf(stdout,"AraEventCalibrator::loadPedestals(): INFO - Pedestal file [from ./calib]"); 00100 } else { 00101 sprintf(calibDir,"%s/share/araCalib",utilEnv); 00102 fprintf(stdout,"AraEventCalibrator::loadPedestals(): INFO - Pedestal file [from ARA_UTIL_INSTALL_DIR/share/calib]"); 00103 } 00104 } 00105 else { 00106 strncpy(calibDir,calibEnv,FILENAME_MAX); 00107 fprintf(stdout,"AraEventCalibrator::loadPedestals(): INFO - Pedestal file [from ARA_CALIB_DIR]"); 00108 } 00109 sprintf(pedFile,"%s/peds_1294924296.869787.run001202.dat",calibDir); 00110 fprintf(stdout," = %s\n",pedFile); 00111 } // end of IF-block for pedestal file not specified by environment variable 00112 else { 00113 strncpy(pedFile,pedFileEnv,FILENAME_MAX); 00114 fprintf(stdout,"AraEventCalibrator::loadPedestals(): INFO - Pedestal file [from ARA_PEDESTAL_FILE] = %s\n",pedFile); 00115 } // end of IF-block for pedestal file specified by environment variable 00116 } 00117 00118 FullLabChipPedStruct_t peds; 00119 gzFile inPed = gzopen(pedFile,"r"); 00120 if( !inPed ){ 00121 fprintf(stderr,"ERROR - Failed to open pedestal file %s.\n",pedFile); 00122 return; 00123 } 00124 00125 int nRead = gzread(inPed,&peds,sizeof(FullLabChipPedStruct_t)); 00126 if( nRead != sizeof(FullLabChipPedStruct_t)){ 00127 int numErr; 00128 fprintf(stderr,"ERROR - Error reading pedestal file %s; %s\n",pedFile,gzerror(inPed,&numErr)); 00129 gzclose(inPed); 00130 return; 00131 } 00132 00133 int chip,chan,samp; 00134 for(chip=0;chip<ACTIVE_CHIPS;++chip) { 00135 for(chan=0;chan<CHANNELS_PER_CHIP;++chan) { 00136 int chanIndex = chip*CHANNELS_PER_CHIP+chan; 00137 for(samp=0;samp<MAX_NUMBER_SAMPLES;++samp) { 00138 pedestalData[chip][chan][samp]=peds.chan[chanIndex].pedMean[samp]; 00139 } 00140 } 00141 } 00142 gzclose(inPed); 00143 } 00144 00145 int AraEventCalibrator::doBinCalibration(UsefulAraEvent *theEvent, int chanIndex,int overrideRCO) 00146 { 00147 int nChip=theEvent->chan[chanIndex].chanId/CHANNELS_PER_CHIP; 00148 int nChan=theEvent->chan[chanIndex].chanId%CHANNELS_PER_CHIP; 00149 int rco=overrideRCO; 00150 if(overrideRCO!=0 && overrideRCO!=1) 00151 rco=theEvent->getRCO(chanIndex); 00152 int hbwrap = theEvent->chan[chanIndex].chipIdFlag&0x08; 00153 char hbextra = (theEvent->chan[chanIndex].chipIdFlag&0xf0)>>4; 00154 short hbstart=theEvent->chan[chanIndex].firstHitbus; 00155 short hbend=theEvent->chan[chanIndex].lastHitbus+hbextra; 00156 00157 00158 00159 double calTime=0; 00160 for(int samp=0;samp<MAX_NUMBER_SAMPLES;++samp){ 00161 rawadc[samp]=theEvent->chan[chanIndex].data[samp]; 00162 if(theEvent->chan[chanIndex].data[samp]==0){ 00163 calwv[samp]=0; 00164 pedsubadc[samp]=0; 00165 }else{ 00166 pedsubadc[samp]=rawadc[samp]-pedestalData[nChip][nChan][samp]; 00167 calwv[samp]=pedsubadc[samp]*ADCMV; 00168 if(calwv[samp]>SATURATION) calwv[samp]=SATURATION; 00169 if(calwv[samp]<-1*SATURATION) calwv[samp]=-1*SATURATION; 00170 } 00171 } 00172 00173 00174 if(nChan==0 || (overrideRCO==0 || overrideRCO==1)) { 00175 //Do the calibration for each chip 00176 calTime=0; 00177 int ir=0; 00178 if(hbwrap){ // Wrapped hitbus 00179 for(int samp=hbstart+1;samp<hbend;++samp) { 00180 tempTimeNums[ir++]=calTime; 00181 calTime+=binWidths[nChip][rco][samp]; 00182 } 00183 } 00184 else{ 00185 for(int samp=hbend+1;samp<MAX_NUMBER_SAMPLES;++samp) { 00186 tempTimeNums[ir++]=calTime; 00187 calTime+=binWidths[nChip][1-rco][samp]; 00188 } 00189 //Now add epsilon 00190 calTime+=epsilonVals[nChip][rco]; //Need to check if this is rco or 1-rco 00191 for(int samp=0;samp<hbstart;++samp) { 00192 tempTimeNums[ir++]=calTime; 00193 calTime+=binWidths[nChip][rco][samp]; 00194 } 00195 } 00196 for(int samp=ir;samp<MAX_NUMBER_SAMPLES;++samp) { 00197 tempTimeNums[samp]=calTime; 00198 calTime+=1; 00199 } 00200 TMath::Sort(MAX_NUMBER_SAMPLES,tempTimeNums,indexNums,kFALSE); 00201 } 00202 // ... and rotate 00203 int ir=0; 00204 int numValid=0; 00205 if(hbwrap){ // Wrapped hitbus 00206 for(int samp=hbstart+1;samp<hbend;++samp) 00207 v[ir++]=calwv[samp]; 00208 }else{ 00209 for(int samp=hbend+1;samp<MAX_NUMBER_SAMPLES;++samp) 00210 v[ir++]=calwv[samp]; 00211 for(int samp=0;samp<hbstart;++samp) 00212 v[ir++]=calwv[samp]; 00213 } 00214 numValid=ir; 00215 // Fill in remaining bins with zeros 00216 for(int samp=ir;samp<MAX_NUMBER_SAMPLES;++samp) 00217 v[samp]=0; 00218 00219 //Now we just have to make sure the times are monotonically increasing 00220 for(int i=0;i<MAX_NUMBER_SAMPLES;i++) { 00221 calTimeNums[i]=tempTimeNums[indexNums[i]]; 00222 calVoltNums[i]=v[indexNums[i]]; 00223 // std::cout << i << "\t" << indexNums[i] << "\t" << calTimeNums[i] << "\t" << calVoltNums[i] << "\n"; 00224 } 00225 return numValid; 00226 } 00227 00228 00229 void AraEventCalibrator::calibrateEvent(UsefulAraEvent *theEvent, AraCalType::AraCalType_t calType) 00230 { 00231 00232 static int gotPeds=0; 00233 if(!gotPeds) 00234 loadPedestals(); 00235 gotPeds=1; 00236 if(AraCalType::hasBinWidthCalib(calType)) 00237 theEvent->guessRCO(0); //Forces the calculation of the RCO phase from the clock 00238 00239 00240 // Calibrate waveforms 00241 for(int samp=0;samp<MAX_NUMBER_SAMPLES;++samp){ 00242 sampNums[samp]=samp; 00243 timeNums[samp]=samp*NSPERSAMP; 00244 } 00245 00246 for(int chanIndex = 0; chanIndex < NUM_DIGITIZED_CHANNELS; ++chanIndex ){ 00247 int numValid=doBinCalibration(theEvent,chanIndex); 00248 00249 00250 00251 //Now we stuff it back into the UsefulAraEvent object 00252 00253 if(calType==AraCalType::kNoCalib) { 00254 theEvent->fNumPoints[chanIndex]=MAX_NUMBER_SAMPLES; 00255 for(int samp=0;samp<MAX_NUMBER_SAMPLES;samp++) { 00256 theEvent->fVolts[chanIndex][samp]=rawadc[samp]; 00257 theEvent->fTimes[chanIndex][samp]=sampNums[samp]; 00258 } 00259 } 00260 if(calType==AraCalType::kJustUnwrap || calType==AraCalType::kADC) { 00261 theEvent->fNumPoints[chanIndex]=numValid; 00262 for(int samp=0;samp<MAX_NUMBER_SAMPLES;samp++) { 00263 theEvent->fTimes[chanIndex][samp]=sampNums[samp]; 00264 if(samp<numValid) { 00265 theEvent->fVolts[chanIndex][samp]=v[samp]; 00266 } 00267 else { 00268 theEvent->fVolts[chanIndex][samp]=0; 00269 } 00270 } 00271 } 00272 if(calType==AraCalType::kVoltageTime) { 00273 theEvent->fNumPoints[chanIndex]=numValid; 00274 for(int samp=0;samp<MAX_NUMBER_SAMPLES;samp++) { 00275 theEvent->fTimes[chanIndex][samp]=timeNums[samp]; 00276 if(samp<numValid) { 00277 theEvent->fVolts[chanIndex][samp]=v[samp]; 00278 } 00279 else { 00280 theEvent->fVolts[chanIndex][samp]=0; 00281 } 00282 } 00283 } 00284 if(calType==AraCalType::kJustPed) { 00285 theEvent->fNumPoints[chanIndex]=MAX_NUMBER_SAMPLES; 00286 for(int samp=0;samp<MAX_NUMBER_SAMPLES;samp++) { 00287 theEvent->fVolts[chanIndex][samp]=pedsubadc[samp]; 00288 theEvent->fTimes[chanIndex][samp]=sampNums[samp]; 00289 } 00290 } 00291 if(AraCalType::hasBinWidthCalib(calType)) { 00292 //Almost always want this 00293 theEvent->fNumPoints[chanIndex]=numValid; 00294 for(int samp=0;samp<MAX_NUMBER_SAMPLES;samp++) { 00295 theEvent->fTimes[chanIndex][samp]=calTimeNums[samp]; 00296 if(samp<numValid) { 00297 theEvent->fVolts[chanIndex][samp]=calVoltNums[samp]; 00298 } 00299 else { 00300 theEvent->fVolts[chanIndex][samp]=0; 00301 } 00302 } 00303 } 00304 } 00305 00306 //Now we have done the initial bin-by-bin and epsilon calibrations 00307 //Next up is to do the clock alignment 00308 if(AraCalType::hasClockAlignment(calType)) { 00309 //All of the higher calibrations do some form of clock alignment 00310 calcClockAlignVals(theEvent,calType); 00311 for(int chanIndex = 0; chanIndex < NUM_DIGITIZED_CHANNELS; ++chanIndex ){ 00312 int nChip=theEvent->chan[chanIndex].chanId/CHANNELS_PER_CHIP; 00313 for(int samp=0;samp<MAX_NUMBER_SAMPLES;samp++) { 00314 theEvent->fTimes[chanIndex][samp]+=clockAlignVals[nChip]; 00315 } 00316 } 00317 } 00318 00319 00320 00321 00322 //For now we just have the one calibration type for interleaving 00323 AraGeomTool *tempGeom = AraGeomTool::Instance(); 00324 for(int rfchan = 0; rfchan < RFCHANS_PER_STATION; ++rfchan ){ 00325 memset(theEvent->fVoltsRF[rfchan],0,sizeof(Double_t)*2*MAX_NUMBER_SAMPLES); 00326 memset(theEvent->fTimesRF[rfchan],0,sizeof(Double_t)*2*MAX_NUMBER_SAMPLES); 00327 if(tempGeom->getNumLabChansForChan(rfchan)==2) { 00328 // std::cout << chan << "\t" 00329 // << tempGeom->getFirstLabChanIndexForChan(rfchan) << "\t" 00330 // << tempGeom->getSecondLabChanIndexForChan(rfchan) << "\n"; 00331 int ci1=tempGeom->getFirstLabChanIndexForChan(rfchan); 00332 int ci2=tempGeom->getSecondLabChanIndexForChan(rfchan); 00333 theEvent->fNumPointsRF[rfchan]=theEvent->fNumPoints[ci1]+theEvent->fNumPoints[ci2]; 00334 //Need to zero mean, maybe should do this in each half seperately? 00335 //RJN hack 13/01/11 00336 double mean=0; 00337 for(int i=0;i<theEvent->fNumPoints[ci1];i++) { 00338 mean+=theEvent->fVolts[ci1][i]; 00339 } 00340 for(int i=0;i<theEvent->fNumPoints[ci2];i++) { 00341 mean+=theEvent->fVolts[ci2][i]; 00342 } 00343 mean/=theEvent->fNumPointsRF[rfchan]; 00344 00345 //Only the interleaved types have any special calib here 00346 if(AraCalType::hasInterleaveCalib(calType)) { 00347 int i1=0; 00348 int i2=0; 00349 for(int i=0;i<theEvent->fNumPointsRF[rfchan];i++) { 00350 if(i1<theEvent->fNumPoints[ci1] && i2<theEvent->fNumPoints[ci2]) { 00351 //Both in play 00352 if(theEvent->fTimes[ci1][i1]<(theEvent->fTimes[ci2][i2]+interleaveVals[rfchan])) { 00353 theEvent->fTimesRF[rfchan][i]=theEvent->fTimes[ci1][i1]; 00354 theEvent->fVoltsRF[rfchan][i]=theEvent->fVolts[ci1][i1]-mean; 00355 // std::cout << "A: " << i << "\t" << theEvent->fTimesRF[rfchan][i] << "\n"; 00356 00357 i1++; 00358 continue; 00359 } 00360 else { 00361 theEvent->fTimesRF[rfchan][i]=theEvent->fTimes[ci2][i2]+interleaveVals[rfchan]; 00362 theEvent->fVoltsRF[rfchan][i]=theEvent->fVolts[ci2][i2]-mean; 00363 // std::cout << "B: " << i << "\t" << theEvent->fTimesRF[rfchan][i] << "\n"; 00364 i2++; 00365 continue; 00366 } 00367 } 00368 else if(i1<theEvent->fNumPoints[ci1]) { 00369 theEvent->fTimesRF[rfchan][i]=theEvent->fTimes[ci1][i1]; 00370 theEvent->fVoltsRF[rfchan][i]=theEvent->fVolts[ci1][i1]-mean; 00371 i1++; 00372 // std::cout << "C: " << i << "\t" << theEvent->fTimesRF[rfchan][i] << "\n"; 00373 continue; 00374 } 00375 else if(i2<theEvent->fNumPoints[ci2]) { 00376 00377 theEvent->fTimesRF[rfchan][i]=theEvent->fTimes[ci2][i2]+interleaveVals[rfchan]; 00378 theEvent->fVoltsRF[rfchan][i]=theEvent->fVolts[ci2][i2]-mean; 00379 // std::cout << "D: " << i << "\t" << theEvent->fTimesRF[rfchan][i] << "\n"; 00380 i2++; 00381 continue; 00382 } 00383 } 00384 } 00385 00386 else { 00387 for(int i=0;i<theEvent->fNumPointsRF[rfchan];i++) { 00388 if(i%2==0) { 00389 //ci2 00390 theEvent->fVoltsRF[rfchan][i]=theEvent->fVolts[ci2][i/2]; 00391 theEvent->fTimesRF[rfchan][i]=theEvent->fTimes[ci2][i/2]; 00392 } 00393 else { 00394 //ci1 00395 theEvent->fVoltsRF[rfchan][i]=theEvent->fVolts[ci1][i/2]; 00396 theEvent->fTimesRF[rfchan][i]=theEvent->fTimes[ci1][i/2]+0.5*NSPERSAMP; 00397 } 00398 00399 } 00400 } 00401 00402 } 00403 else { 00404 // std::cout << rfchan << "\t" 00405 // << tempGeom->getFirstLabChanIndexForChan(rfchan) << "\n"; 00406 int ci=tempGeom->getFirstLabChanIndexForChan(rfchan); 00407 theEvent->fNumPointsRF[rfchan]=theEvent->fNumPoints[ci]; 00408 00409 //Need to zero mean the data 00410 double mean=0; 00411 for(int i=0;i<theEvent->fNumPoints[ci];i++) { 00412 mean+=theEvent->fVolts[ci][i]; 00413 } 00414 mean/=theEvent->fNumPoints[ci]; 00415 00416 for(int i=0;i<theEvent->fNumPointsRF[rfchan];i++) { 00417 theEvent->fVoltsRF[rfchan][i]=theEvent->fVolts[ci][i]-mean; 00418 theEvent->fTimesRF[rfchan][i]=theEvent->fTimes[ci][i]; 00419 00420 } 00421 } 00422 00423 if(AraCalType::hasCableDelays(calType)) { 00424 Double_t delay=tempGeom->fAntInfo[rfchan].cableDelay; 00425 // delay-=180; //Just an arbitrary offset 00426 for(int i=0;i<theEvent->fNumPointsRF[rfchan];i++) { 00427 theEvent->fTimesRF[rfchan][i]-=delay; 00428 } 00429 } 00430 00431 00432 } 00433 00434 } 00435 00436 00437 void AraEventCalibrator::loadCalib() 00438 { 00439 char calibFile[FILENAME_MAX]; 00440 char calibDir[FILENAME_MAX]; 00441 char *calibEnv=getenv("ARA_CALIB_DIR"); 00442 if(!calibEnv) { 00443 char *utilEnv=getenv("ARA_UTIL_INSTALL_DIR"); 00444 if(!utilEnv) 00445 sprintf(calibDir,"calib"); 00446 else 00447 sprintf(calibDir,"%s/share/araCalib",utilEnv); 00448 } 00449 else { 00450 strncpy(calibDir,calibEnv,FILENAME_MAX); 00451 } 00452 int chip,rco,chan; 00453 //Bin Width Calib 00454 sprintf(calibFile,"%s/binWidths.txt",calibDir); 00455 std::ifstream BinFile(calibFile); 00456 double width; 00457 while(BinFile >> chip >> rco) { 00458 for(int samp=0;samp<MAX_NUMBER_SAMPLES;samp++) { 00459 BinFile >> width; 00460 binWidths[chip][rco][samp]=width; 00461 } 00462 } 00463 //Epsilon Calib 00464 sprintf(calibFile,"%s/epsilonFile.txt",calibDir); 00465 std::ifstream EpsFile(calibFile); 00466 double epsilon; 00467 while(EpsFile >> chip >> rco >> epsilon) { 00468 epsilonVals[chip][rco]=epsilon; 00469 } 00470 //Interleave Calib 00471 sprintf(calibFile,"%s/interleaveFile.txt",calibDir); 00472 std::ifstream IntFile(calibFile); 00473 double interleave; 00474 while(IntFile >> chip >> chan >> interleave) { 00475 interleaveVals[chan+4*chip]=interleave; 00476 } 00477 } 00478 00479 00480 00481 void AraEventCalibrator::calcClockAlignVals(UsefulAraEvent *theEvent, AraCalType::AraCalType_t calType) 00482 { 00483 if(!AraCalType::hasClockAlignment(calType)) return; 00484 TGraph *grClock[ACTIVE_CHIPS]={0}; 00485 Double_t lag[ACTIVE_CHIPS]={0}; 00486 for(int chip=0;chip<ACTIVE_CHIPS;chip++) { 00487 clockAlignVals[chip]=0; 00488 int chanIndex=TESTBED1_CLOCK_CHANNEL+CHANNELS_PER_CHIP*chip; 00489 grClock[chip]=theEvent->getGraphFromElecChan(chanIndex); 00490 lag[chip]=estimateClockLag(grClock[chip]); 00491 delete grClock[chip]; 00492 00493 if(chip>0) { 00494 //Then can actually do some alignment 00495 clockAlignVals[chip]=lag[0]-lag[chip]; 00496 //The below fudge factors were "tuned" using pulser data 00497 // to try and remove period ambiguities resulting from wrong cycle lag 00498 if(lag[chip]<8 && lag[0]>9) 00499 clockAlignVals[chip]-=25; 00500 if(lag[chip]>9 && lag[0]<7) 00501 clockAlignVals[chip]+=25; 00502 // std::cout << "clockAlignVals[ " << chip << "] = " << clockAlignVals[chip] << "\n"; 00503 } 00504 00505 } 00506 } 00507 00508 00509 Double_t AraEventCalibrator::estimateClockLag(TGraph *grClock) 00510 { 00511 // This funciton estimates the clock lag (i.e. phase but expressed in terms of a deltaT between 0 and 1 period) by just using all the negative-positive zero crossing 00512 00513 Double_t period=TESTBED1_CLOCK_PERIOD; 00514 Double_t mean=grClock->GetMean(2); 00515 Int_t numPoints=grClock->GetN(); 00516 if(numPoints<3) return 0; 00517 Double_t *tVals=grClock->GetX(); 00518 Double_t *vVals=grClock->GetY(); 00519 00520 Double_t zc[1000]={0}; 00521 Double_t rawZc[1000]={0}; 00522 int countZC=0; 00523 for(int i=2;i<numPoints;i++) { 00524 if(vVals[i-1]<0 && vVals[i]>0) { 00525 Double_t x1=tVals[i-1]; 00526 Double_t x2=tVals[i]; 00527 Double_t y1=vVals[i-1]-mean; 00528 Double_t y2=vVals[i]-mean; 00529 // std::cout << i << "\t" << y2 << "\t" << y1 << "\t" << (y2-y1) << "\n"; 00530 zc[countZC]=(((0-y1)/(y2-y1))*(x2-x1))+x1; 00531 rawZc[countZC]=zc[countZC]; 00532 countZC++; 00533 // if(countZC==1) 00534 // break; 00535 } 00536 00537 } 00538 00539 Double_t firstZC=zc[0]; 00540 while(firstZC>period) firstZC-=period; 00541 Double_t meanZC=0; 00542 Double_t meanZC2=0; 00543 for(int i=0;i<countZC;i++) { 00544 while((zc[i])>period) zc[i]-=period; 00545 if(TMath::Abs((zc[i]-period)-firstZC)<TMath::Abs(zc[i]-firstZC)) 00546 zc[i]-=period; 00547 if(TMath::Abs((zc[i]+period)-firstZC)<TMath::Abs(zc[i]-firstZC)) 00548 zc[i]+=period; 00549 meanZC+=zc[i]; 00550 meanZC2+=zc[i]*zc[i]; 00551 // std::cout << i << "\t" << zc[i] << "\t" << rawZc[i] << "\n"; 00552 } 00553 meanZC/=countZC; 00554 meanZC2/=countZC; 00555 // Double_t rms=TMath::Sqrt(meanZC2-meanZC*meanZC); 00556 // std::cout << meanZC << "\t" << rms << "\n"; 00557 return meanZC; 00558 00559 } 00560 00561 void AraEventCalibrator::fillRCOGuessArray(UsefulAraEvent *theEvent, int rcoGuess[ACTIVE_CHIPS]) 00562 { 00563 00564 for(int chip=0;chip<ACTIVE_CHIPS;chip++) { 00565 int chanIndex=TESTBED1_CLOCK_CHANNEL+CHANNELS_PER_CHIP*chip; 00566 rcoGuess[chip]=theEvent->getRawRCO(chanIndex); 00567 00568 Double_t period[2]={0}; 00569 Double_t rms[2]={0}; 00570 for(int rcoTest=0;rcoTest<2;rcoTest++) { 00571 int numValid=doBinCalibration(theEvent,chanIndex,rcoTest); 00572 period[rcoTest]=estimateClockPeriod(numValid,rms[rcoTest]); 00573 } 00574 00575 Double_t periodTest=(TMath::Abs(period[0]-TESTBED1_CLOCK_PERIOD)-TMath::Abs(period[1]-TESTBED1_CLOCK_PERIOD)); 00576 Double_t rmsTest=(rms[0]-rms[1]); 00577 if(periodTest<0) { 00578 rcoGuess[chip]=0; 00579 if(TMath::Abs(periodTest)<0.5 && rmsTest>0) 00580 rcoGuess[chip]=1; 00581 } 00582 else { 00583 rcoGuess[chip]=1; 00584 if(TMath::Abs(periodTest)<0.5 && rmsTest<0) { 00585 rcoGuess[chip]=0; 00586 } 00587 } 00588 if(rms[rcoGuess[chip]]>4) { 00589 rcoGuess[chip]=theEvent->getRawRCO(chanIndex); 00590 } 00591 00592 // std::cout << "AraEventCalibrator:\t" << period[0] << "\t" << period[1] << "\n"; 00593 // std::cout << "AraEventCalibrator:\t" << periodTest << "\t" << rmsTest << "\t" << rcoGuess[chip] << "\n"; 00594 } 00595 } 00596 00597 00598 00599 Double_t AraEventCalibrator::estimateClockPeriod(Int_t numPoints, Double_t &rms) 00600 { 00601 // This funciton estimates the period by just using all the negative-positive zero crossing 00602 if(numPoints<3) return 0; 00603 Double_t mean=0; 00604 Double_t vVals[MAX_NUMBER_SAMPLES]={0}; 00605 for(int i=0;i<numPoints;i++) { 00606 mean+=calVoltNums[i]; 00607 } 00608 mean/=numPoints; 00609 for(int i=0;i<numPoints;i++) { 00610 vVals[i]=calVoltNums[i]-mean; 00611 } 00612 00613 00614 Double_t zc[1000]={0}; 00615 Double_t periods[1000]={0}; 00616 int countZC=0; 00617 for(int i=2;i<numPoints;i++) { 00618 if(vVals[i-1]<0 && vVals[i]>0) { 00619 Double_t x1=calTimeNums[i-1]; 00620 Double_t x2=calTimeNums[i]; 00621 Double_t y1=vVals[i-1]; 00622 Double_t y2=vVals[i]; 00623 // std::cout << i << "\t" << y2 << "\t" << y1 << "\t" << (y2-y1) << "\n"; 00624 Double_t zcTime=(((0-y1)/(y2-y1))*(x2-x1))+x1; 00625 if(countZC>0) { 00626 if((zcTime-zc[countZC-1])<10) 00627 continue; 00628 } 00629 zc[countZC]=zcTime; 00630 countZC++; 00631 // if(countZC==1) 00632 // break; 00633 } 00634 } 00635 00636 if(countZC<2) return 0; 00637 00638 00639 int countPeriods=0; 00640 Double_t meanPeriod=0; 00641 Double_t meanPeriodSq=0; 00642 for(int i=1;i<countZC;i++) { 00643 periods[countPeriods]=zc[i]-zc[i-1]; 00644 meanPeriod+=periods[countPeriods]; 00645 meanPeriodSq+=periods[countPeriods]*periods[countPeriods]; 00646 countPeriods++; 00647 } 00648 meanPeriod/=countPeriods; 00649 meanPeriodSq/=countPeriods; 00650 rms=TMath::Sqrt(meanPeriodSq-meanPeriod*meanPeriod); 00651 00652 return meanPeriod; 00653 }
Generated on Wed Aug 8 16:18:55 2012 for ARA ROOT Test Bed Software by
