ARA ROOT Test BEd Software

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 doxygen 1.4.7