Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

FarProcessor.cxx

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <math.h>
00003 #include "ReadoutSim/FarProcessor.h"
00004 
00005 using namespace rsim;
00006 
00007 FarProcessor::FarProcessor()
00008 {
00009   MIPSignal=20.0; // 20 pe's/MIP
00010   DarkCurrent=0.250; //Prob of elec in sample period
00011   ASIC_Noise=1.50; //150e- divided by gain of 100
00012   ExcessNoise=2.5; // APD amplification excess noise factor
00013   
00014   maxADC=4096;
00015 
00016   T_F = 10.0;
00017   T_R = 2.0;
00018 
00019   pRandom          = new TRandom(100);
00020 }
00021 
00022 FarProcessor::~FarProcessor()
00023 {
00024   delete pRandom;
00025 }
00026 
00027 void FarProcessor::Configure(const cfg::Config& c)
00028 {
00029   c("MIPSignal").Get(MIPSignal);
00030   c("DarkCurrent").Get(DarkCurrent);
00031   c("ASIC_Noise").Get(ASIC_Noise);
00032   c("ExcessNoise").Get(ExcessNoise);
00033   c("maxADC").Get(maxADC);
00034   c("T_F").Get(T_F);
00035   c("T_R").Get(T_R);
00036   c("MessageLevel").Get(msglevel);
00037 }
00038 
00039 void FarProcessor::ProcessChannel(std::vector<unsigned short>& ADC, std::vector<unsigned short>& TDC,
00040                                   std::vector<sim::HitProfile> & MCInfo)
00041 {
00042   //All times in units of sample time.  Assumed to be 500ns for FD.
00043   
00044   MaxHeight=TMath::Power(T_F/T_R,-T_R/(T_F-T_R))-
00045     TMath::Power(T_F/T_R,-T_F/(T_F-T_R));  //peak of a pulse with risetime T_R and falltime T_F
00046   //cout << T_R << " " << T_F  << " " <<MaxHeight << endl;
00047   
00048   //  TCanvas *test = new TCanvas("test","test",800,800);
00049   const Int_t maxArray=1000;
00050   static Double_t Input[maxArray];
00051   static Double_t Output[maxArray];
00052   static Double_t Interp_Out[8*maxArray];
00053   for (Int_t Interp_index = 0 ; Interp_index < 8*maxArray ; Interp_index++)
00054     Interp_Out[Interp_index]=0.0;
00055   static Double_t DCS[maxArray];
00056   static Double_t Convolution[maxArray];
00057   static Double_t Index[maxArray];
00058   static Double_t PerfectSignal[8][20];  //Perfect signal in 8 steps of phase, 20 steps of digitization
00059   
00060   static Int_t PSmade=0;
00061   
00062   //Clear input array
00063   for (Int_t i=0;i<maxArray;i++) Input[i]=0.0;
00064   
00065   // For MC information. First prepare the vector of pair<index, ADC> for each array component
00066   sim::HitProfile tempprofile;
00067   const unsigned int knoise = tempprofile.NoiseId();
00068   static std::vector< std::pair<unsigned int, Double_t> > InputComponent[maxArray];
00069   static std::vector< std::pair<unsigned int, Double_t> > OutputComponent[maxArray];
00070   static std::vector< std::pair<unsigned int, Double_t> > Interp_OutComponent[8*maxArray];
00071   static std::vector< std::pair<unsigned int, Double_t> > ConvolutionComponent[maxArray];
00072   
00073   //Clear MC array
00074   for (Int_t i=0;i<maxArray;i++) {
00075     InputComponent[i].clear();
00076     OutputComponent[i].clear();
00077   }
00078   for (Int_t Interp_index = 0 ; Interp_index < 8*maxArray ; Interp_index++)
00079     Interp_OutComponent[Interp_index].clear();
00080   
00081   //Add signal
00082   // Input[20]=1.0*MIPSignal;
00083   //  Input[50]=1.0*MIPSignal;
00084   //  Input[60]=1.0*MIPSignal;
00085   //  Input[150]=0.50*MIPSignal;
00086   //  Input[300]=1.0*MIPSignal;
00087   //  Input[250]=1.0*MIPSignal;
00088   //  Input[350]=5.0*MIPSignal;
00089   
00091   //really add signals
00092   
00093   static int startsignal=50;
00094   
00095   std::pair<unsigned int, Double_t> tempindex;
00096   
00097   for(unsigned int i=0;i<ADC.size();i++)
00098   {
00099     //TDC is recorded in ns... each bin in 500 ns
00100     //first TDC should be in at least bin 50 to allow for ramp up of any noise
00101     int tbin = (TDC[i]-TDC[0])/500+startsignal;
00102     if (tbin>maxArray) 
00103     {
00104       //printf("error.... length of signal exceeds array size\n");
00105       continue;
00106     }
00107     
00108     Input[tbin]+=ADC[i];
00109     tempindex.first  = i;
00110     tempindex.second = ADC[i];
00111     InputComponent[tbin].push_back(tempindex);
00112     //printf("%d %f - ",i, TDC[i]);
00113   }//printf("\n");
00114   
00115   TDC.clear();
00116   ADC.clear();
00117   
00118   std::vector<sim::HitProfile> copyMCInfo = MCInfo;
00119   MCInfo.clear();
00120   
00122   
00123   //printf("adding dark current\n");
00124   
00125   for (Int_t i=0;i<maxArray;i++) {
00126     //add random dark current
00127     Double_t darkcurrent = pRandom->Poisson(DarkCurrent);
00128     Input[i]+=darkcurrent;
00129     
00130     tempindex.first = knoise;
00131     tempindex.second = darkcurrent;
00132     InputComponent[i].push_back(tempindex);
00133     
00134     if (Input[i]>0.0) {
00135       //smear by apd excess noise response
00136       Double_t smeared = pRandom->Gaus(Input[i],TMath::Sqrt(Input[i]*(ExcessNoise-1))); 
00137       
00138       for(unsigned int j=0; j<InputComponent[i].size(); j++) { 
00139         InputComponent[i][j].second *= smeared/Input[i];
00140       }
00141       
00142       Input[i] = smeared;
00143     }
00144     Output[i]=0.0;
00145     Index[i]=(Double_t)i;
00146   }
00147   
00148   // Create a perfect signal in 8 steps of phase to match 8x interpolation.
00149   
00150   //printf("perfect signal\n");
00151   
00152   if(PSmade<1)
00153     for (Int_t phase=0;phase<8;phase++){
00154       PerfectSignal[phase][0]=0.0;
00155       // PerfSig->SetBinContent(0,phase,0.0);
00156       for (Int_t step=1;step<20;step++){
00157         PerfectSignal[phase][step]=exp(-(step-1+(float)phase/8.0)/T_F)*(1-exp(-(step-1+(float)phase/8.0)/T_R));
00158         //  PerfSig->SetBinContent(step+1,phase+1,PerfectSignal[phase][step]);   
00159       }
00160     }
00161   PSmade=1;
00162   
00163   //printf("output and dcs\n");
00164   
00165   Double_t ConvFudge = 0.2; //Fudge factor to get convolution on same scale.
00166   
00167   for (Int_t a=0 ;  a < 5*T_F; a++){
00168     Double_t fun=exp(-(a)/T_F)*(1-exp(-(a)/T_R))/MaxHeight;
00169     for (Int_t i=0; i<maxArray ; i++){
00170       if(i-a>=0) {
00171         Output[i]+=Input[i-a]*fun;              
00172         
00173         if(fun==0) continue;
00174 
00175         for(unsigned int j=0; j<InputComponent[i-a].size(); j++) {
00176 
00177           tempindex.first  = InputComponent[i-a][j].first;
00178           tempindex.second = fun * InputComponent[i-a][j].second;
00179 
00180           bool duplicated = false;
00181           for(unsigned int k=0; k<OutputComponent[i].size(); k++) {
00182             if(OutputComponent[i][k].first == tempindex.first) {
00183               OutputComponent[i][k].second += tempindex.second;
00184               duplicated = true;
00185             }
00186           }
00187           if (!duplicated) OutputComponent[i].push_back(tempindex);
00188         }
00189 
00190       }
00191     }
00192   }
00193   
00194   tempindex.first = knoise;
00195   
00196   Double_t asicnoise;
00197   
00198   asicnoise = pRandom->Gaus(0,ASIC_Noise);
00199   Output[0] += asicnoise;
00200   tempindex.second = asicnoise;
00201   OutputComponent[1].push_back(tempindex);
00202   
00203   asicnoise=pRandom->Gaus(0,ASIC_Noise);
00204   Output[1] += asicnoise;
00205   tempindex.second = asicnoise;
00206   OutputComponent[2].push_back(tempindex);
00207   
00208   for (Int_t i=2; i<maxArray ; i++){
00209     asicnoise = pRandom->Gaus(0,ASIC_Noise);
00210     Output[i] += asicnoise;
00211     tempindex.second = asicnoise;
00212     OutputComponent[i].push_back(tempindex);
00213     
00214     DCS[i-1]=Output[i]-Output[i-2];
00215   }
00216   
00217   // clock_t tho;
00218   //tho=clock();
00219   
00220   //printf("int out\n");
00221   
00222   Double_t x_interp[640];
00223   
00224   //this should be put in a seperate static class
00225   for (Int_t Interp_index = -320;  Interp_index < 320 ; Interp_index++)
00226   {
00227     x_interp[Interp_index+320]=(Double_t)Interp_index*TMath::Pi()/8.0;
00228     
00229     if( fabs(x_interp[Interp_index+320]) > 1.0E-3)
00230       x_interp[Interp_index+320]=1.0*TMath::Sin(x_interp[Interp_index+320])/x_interp[Interp_index+320];
00231     else
00232       x_interp[Interp_index+320]=1;
00233     
00234   }
00236   //Interpolate Output to add 8X the points with sin(x)/x
00237   //Truncate after 40 periods of sinx oscillation
00238   for (Int_t Interp_index = -320;  Interp_index < 320 ; Interp_index++)
00239   {
00240     //Double_t x_interp=(Double_t)Interp_index*TMath::Pi()/8.0;
00241     
00242     //if( fabs(x_interp) > 1.0E-3)
00243     //  {
00244     //          Double_t fun=1.0*TMath::Sin(x_interp)/x_interp;
00245     
00246     //for (Int_t Sample_index = 40 ; Sample_index < maxArray && Sample_index*8+Interp_index >0 && Sample_index*8+Interp_index < maxArray ; Sample_index++)
00247     for (Int_t Sample_index = -Interp_index/8 ; Sample_index < (maxArray -Interp_index)/8  ; Sample_index++)
00248     {     
00249       Interp_Out[Sample_index*8+Interp_index] +=
00250         Output[Sample_index]*x_interp[Interp_index+320];
00251       /*
00252       for(unsigned int j=0; j<OutputComponent[Sample_index].size(); j++) {
00253         tempindex.first  = OutputComponent[Sample_index][j].first;
00254         tempindex.second = x_interp[Interp_index+320] * OutputComponent[Sample_index][j].second;
00255         Interp_OutComponent[Sample_index*8+Interp_index].push_back(tempindex);
00256       }
00257       */
00258     }
00259     
00260     //} else {
00261     
00262     //  for (Int_t Sample_index = -Interp_index/8 ; Sample_index < (maxArray -Interp_index)/8  ; Sample_index++)
00263     //  Interp_Out[Sample_index*8+Interp_index] += Output[Sample_index];
00264     
00265     //}
00266   }
00267   
00268   //tho-=clock(); //printf ("It took you %d ticks \n", -tho );
00269   
00270   //printf("conv\n");
00271   for (Int_t i=0; i<maxArray ; i++){
00272     //Convolution with perfect signal (Still needs to use all phases.)
00273     Convolution[i]=0.0;
00274     ConvolutionComponent[i].clear();
00275     if (i>20) {
00276       for (Int_t i_t=i;i-i_t<20;i_t--) {
00277         
00278         Convolution[i] += ConvFudge*PerfectSignal[0][20-(i-i_t)]*Output[i_t];
00279 
00280         for(unsigned int j=0; j<OutputComponent[i_t].size(); j++) {
00281           
00282           tempindex.first  = OutputComponent[i_t][j].first;
00283           tempindex.second = ConvFudge * PerfectSignal[0][20-(i-i_t)] * OutputComponent[i_t][j].second;
00284           
00285           bool duplicated = false;
00286           for(unsigned int k=0; k<ConvolutionComponent[i].size(); k++) {
00287             if(ConvolutionComponent[i][k].first == tempindex.first) {
00288               ConvolutionComponent[i][k].second += tempindex.second;
00289               duplicated = true;
00290             }
00291           }
00292           if (!duplicated) {
00293             ConvolutionComponent[i].push_back(tempindex);
00294           }
00295         }
00296 
00297       }  
00298     }
00299   }    
00300 
00301   //printf("making output\n");
00302   
00303   Int_t maxbin=-1;
00304   Float_t maxval=-1;
00305   Float_t thresh=20;
00306 
00307   //std::vector<float> ADC(0);
00308   //std::vector<float> TDC(0);
00309   
00310   for (Int_t i=0; i<maxArray ; i++){
00311     if(Convolution[i]>thresh)
00312     {
00313       if(Convolution[i]>maxval)
00314       {
00315         maxbin=i;
00316         maxval=Convolution[i];
00317       }
00318     }else{
00319       if(maxval>0)
00320       {
00322         ADC.push_back(maxval>maxADC ? maxADC : (short)maxval);
00323         TDC.push_back((short)(maxbin-19-startsignal));  
00324 
00325         tempprofile.Clear();
00326         
00327         for(unsigned int j=0; j<ConvolutionComponent[maxbin].size(); j++) {
00328           
00329           unsigned int hitindex = ConvolutionComponent[maxbin][j].first;
00330           
00331           if(hitindex==knoise) {
00332             tempprofile.Push(tempprofile.NoiseId(),ConvolutionComponent[maxbin][j].second);
00333           } else {
00334             for(unsigned int k=0; k<copyMCInfo[hitindex].NComponents(); k++) {
00335               tempprofile.Push(copyMCInfo[hitindex].Component(k,(float)ConvolutionComponent[maxbin][j].second));
00336             }
00337           }       
00338         }
00339         
00340         tempprofile.Combine();
00341         tempprofile.NormalizeFraction();
00342 
00343         MCInfo.push_back(tempprofile);
00344         
00345       }
00346       maxbin=-1;
00347       maxval=-1;
00348     }
00349   }
00350   
00351   if(maxval>0)
00352   {
00354     ADC.push_back(maxval>maxADC ? maxADC : (short)maxval);
00355     TDC.push_back((short)(maxbin-19-startsignal));      
00356     
00357     tempprofile.Clear();
00358     
00359     for(unsigned int j=0; j<ConvolutionComponent[maxbin].size(); j++) {
00360       
00361       unsigned int hitindex = ConvolutionComponent[maxbin][j].first;
00362       
00363       if(hitindex==knoise) {
00364         tempprofile.Push(tempprofile.NoiseId(),ConvolutionComponent[maxbin][j].second);
00365       } else {
00366         for(unsigned int k=0; k<copyMCInfo[hitindex].NComponents(); k++)
00367           tempprofile.Push(copyMCInfo[hitindex].Component(k,(float)ConvolutionComponent[maxbin][j].second));
00368       }   
00369     }
00370     
00371     tempprofile.Combine();
00372     tempprofile.NormalizeFraction();
00373 
00374     MCInfo.push_back(tempprofile);
00375   }
00376 
00377   maxbin=-1;
00378   maxval=-1;
00379   
00380   if(ADC.size()<1)
00381   {
00382     ADC.push_back(0);
00383     TDC.push_back(0);
00384   } else if (ADC.size()>1) {
00385     //printf("possible error... multiple peaks... should dump waveform\n");
00386   } 
00387   
00388   /*
00389     for(unsigned int ii=0;ii<ADC.size();ii++)
00390     {
00391     printf("peak at %d time %d\n",ADC[ii], TDC[ii]);
00392     }
00393   */    
00394 
00395 }

Generated on Mon Dec 1 02:35:17 2008 for NOvA Offline by  doxygen 1.3.9.1