10 #include "Constants.h" 11 #include "icemc_random.h" 18 void Tools::MakeGraph(
int index,
const int n,
double *time,
double *volts,TGraph *&mygraph,TH2F *&h2,
double scalex,
double scaley,
string xaxistitle,
string yaxistitle) {
20 double maxtime=-1.E20;
28 for (
int i=0;i<n;i++) {
30 voltscopy[i]=volts[i];
34 for (
int i=0;i<n;i++) {
35 if (timecopy[i]>maxtime)
37 if (timecopy[i]<mintime)
39 if (voltscopy[i]>maxv)
41 if (voltscopy[i]<minv)
45 mygraph=
new TGraph(n,timecopy,voltscopy);
47 h2=
new TH2F(Form(
"h2%d",index),
"",10*n,mintime*1.1,maxtime*1.1,100,minv*1.1,maxv*1.1);
49 h2->SetXTitle(xaxistitle.c_str());
50 h2->SetYTitle(yaxistitle.c_str());
54 int Tools::iSum(
int* thisarray,
int n) {
57 for (
int i=0;i<n;i++) {
64 double Tools::getMaxMagnitude(vector<double> v) {
66 for (
int i=0;i<(int)v.size();i++) {
74 void Tools::ShiftLeft(
double *x,
const int n,
int ishift) {
78 for (
int i=0;i<n;i++) {
81 for (
int i=0;i<n-ishift;i++) {
82 x[i]=x_temp[i+ishift];
84 for (
int i=n-ishift;i<n;i++) {
90 void Tools::ShiftRight(
double *x,
const int n,
int ishift) {
94 for (
int i=0;i<n;i++) {
97 for (
int i=ishift;i<n;i++) {
98 x[i]=x_temp[i-ishift];
100 for (
int i=0;i<ishift;i++) {
106 void Tools::realft(
double *data,
const int isign,
int nsize){
107 int i, i1, i2, i3, i4;
108 double c1=0.5,c2,h1r,h1i,h2r,h2i,wr,wi,wpr,wpi,wtemp,theta;
109 theta=3.141592653589793238/(nsize>>1);
117 wtemp=sin(0.5*theta);
118 wpr = -2.0*wtemp*wtemp;
122 for (i=1;i<(nsize>>2);i++) {
125 h1r=c1*(data[i1]+data[i3]);
126 h1i=c1*(data[i2]-data[i4]);
127 h2r= -c2*(data[i2]+data[i4]);
128 h2i=c2*(data[i1]-data[i3]);
129 data[i1]=h1r+wr*h2r-wi*h2i;
130 data[i2]=h1i+wr*h2i+wi*h2r;
131 data[i3]=h1r-wr*h2r+wi*h2i;
132 data[i4]= -h1i+wr*h2i+wi*h2r;
133 wr=(wtemp=wr)*wpr-wi*wpi+wr;
134 wi=wi*wpr+wtemp*wpi+wi;
137 data[0] = (h1r=data[0])+data[1];
138 data[1] = h1r-data[1];
140 data[0]=c1*((h1r=data[0])+data[1]);
141 data[1]=c1*(h1r-data[1]);
142 four1(data,-1,nsize);
147 void Tools::SWAP(
double &a,
double &b){
154 void Tools::four1(
double *data,
const int isign,
int nsize) {
155 int n,mmax,m,j,istep,i;
156 double wtemp,wr,wpr,wpi,wi,theta,tempr,tempi;
163 SWAP(data[j-1],data[i-1]);
164 SWAP(data[j],data[i]);
167 while (m >= 2 && j > m) {
176 theta=isign*(6.28318530717959/mmax);
177 wtemp=sin(0.5*theta);
178 wpr = -2.0*wtemp*wtemp;
182 for (m=1;m<mmax;m+=2) {
183 for (i=m;i<=n;i+=istep) {
185 tempr=wr*data[j-1]-wi*data[j];
186 tempi=wr*data[j]+wi*data[j-1];
187 data[j-1]=data[i-1]-tempr;
188 data[j]=data[i]-tempi;
192 wr=(wtemp=wr)*wpr-wi*wpi+wr;
193 wi=wi*wpr+wtemp*wpi+wi;
200 double Tools::dSquare(
double *p) {
201 return p[0]*p[0]+p[1]*p[1]+p[2]*p[2];
205 int Tools::WhichIsMin(
double *x,
int n) {
208 for (
int i=0;i<n;i++) {
218 void Tools::Print(
double *p,
int i) {
219 for (
int j=0;j<i;j++) {
226 void Tools::Print(
int *p,
int i) {
227 for (
int j=0;j<i;j++) {
234 void Tools::GetNextNumberAsString(ifstream& fin, ofstream& fout,
string& number) {
238 fout << temp <<
"\n";
241 place=temp.find_first_of(
" \t");
243 number=temp.substr(0,place);
247 void Tools::GetNumbersAsStringArray(ifstream& fin, ofstream& fout,vector<string>& vnumbers,
int nelements) {
257 for (
int n=0;n<nelements;n++) {
260 vnumbers.push_back(s);
266 fout << temp <<
"\n";
271 void Tools::GetNext2NumbersAsString(ifstream& fin,ofstream& fout,
string& number1,
string& number2,
string& stherest) {
276 fout << temp <<
"\n";
279 place=temp.find_first_of(
" \t");
281 number1=temp.substr(0,place);
283 temp=temp.substr(place+1,temp.size());
285 number2=temp.substr(0,temp.find_first_of(
" "));
287 stherest=temp.substr(2,temp.size());
291 double Tools::GetFWHM(TH1 *h1) {
292 int imax=h1->GetMaximumBin();
293 double max=h1->GetMaximum();
299 for (
int ibin=imax;ibin<=h1->GetNbinsX();ibin++) {
300 if (h1->GetBinContent(ibin)<max/2.) {
302 ibin=h1->GetNbinsX()+1;
307 for (
int ibin=imax;ibin>=1;ibin--) {
308 if (h1->GetBinContent(ibin)<max/2.) {
315 if (ibin_plus>0 && ibin_minus==0) {
320 if (ibin_plus==0 && ibin_minus==0) {
321 cout <<
"Found 0 FWHM.\n";
325 return (h1->GetBinCenter(ibin_plus)-h1->GetBinCenter(ibin_minus))/2.;
329 int Tools::NonZero(
double *anarray,
int n) {
331 for (
int i=0;i<n;i++) {
332 cout <<
"i, anarray is " << i <<
"\t" << anarray[i] <<
"\n";
340 void Tools::Zero(
int *anarray,
int n) {
341 for (
int i=0;i<n;i++) {
347 void Tools::Zero(
double *anarray,
int n) {
348 for (
int i=0;i<n;i++) {
352 double Tools::dSum(
double *anarray,
int n) {
354 for (
int i=0;i<n;i++) {
361 double Tools::dMinNotZero(
const double *x,
int n) {
362 double min=dMax(x,n);
364 cout <<
"max is 0.\n";
365 for (
int k=1;k<n;k++) {
366 if (x[k]<min && x[k]!=0)
373 double Tools::dMin(
const double *x,
int n) {
375 for (
int k=1;k<n;k++) {
383 double Tools::dMin(
double x,
double y) {
394 double Tools::dMax(
const double *x,
int n) {
397 for (
int k=1;k<n;k++) {
405 double Tools::dvMax(
const vector<double> x) {
408 for (
int k=1;k<(int)x.size();k++) {
416 double Tools::dsMax(TSpline5 *sp) {
420 for (
int i=0;i<sp->GetNp();i++) {
421 sp->GetKnot(i,blah1,blah2);
424 maxn=Tools::dvMax(y);
429 double Tools::dMax(
double a,
double b) {
440 int Tools::Getifreq(
double freq,
double freq_low,
double freq_high,
int n) {
447 return (
int)((freq-freq_low)/(freq_high-freq_low)*(double)n);
451 void Tools::InterpolateReal(
double* array,
const unsigned n){
453 double previous_nonzero = 0.;
454 double next_nonzero = 0.;
456 unsigned ifirstnonzero = 0;
457 unsigned ilastnonzero = 0;
460 unsigned count_nonzero = 0;
471 for (
unsigned i = 0; i < n; i++) {
478 for (
unsigned i = ifirstnonzero; i < n; i++) {
481 previous_nonzero = array[i];
486 while (check == 0. && k < n) {
491 next_nonzero = check;
492 for (
unsigned j = i; j < k; j++) {
493 array[j] = previous_nonzero + (next_nonzero - previous_nonzero) *
double(j - (i - 1)) /
double(k - (i - 1));
496 previous_nonzero = next_nonzero;
499 ilastnonzero = i - 1;
504 for (
unsigned j = 0; j < n; j++){
505 array[2 * j] *= sqrt(
double(count_nonzero) /
double(ilastnonzero - ifirstnonzero));
511 void Tools::InterpolateComplex(
double *array,
const unsigned n) {
513 double previous_nonzero = 0.;
514 double next_nonzero = 0.;
516 unsigned ifirstnonzero = 0;
517 unsigned ilastnonzero = 0;
520 unsigned count_nonzero = 0;
523 while (array[2 * m] == 0){
530 for (
unsigned i = 0; i < n; i++) {
531 if (array[2 * i] != 0)
537 for (
unsigned i = ifirstnonzero; i < n; i++) {
538 if (array[2 * i] != 0.) {
540 previous_nonzero = array[2 * i];
545 while (check == 0. && k < n) {
546 check = array[2 * k];
550 next_nonzero = check;
551 for (
unsigned j = i; j < k; j++) {
552 array[2 * j] = previous_nonzero + (next_nonzero - previous_nonzero) * (
double)(j - (i - 1)) / (double)(k - (i - 1));
553 array[2 * j + 1] = array[2 * j];
556 previous_nonzero = next_nonzero;
559 ilastnonzero = i - 1;
564 for (
unsigned j = 0; j < n; j++){
565 array[2 * j] *= sqrt((
double)count_nonzero / (
double)(ilastnonzero - ifirstnonzero));
566 array[2 * j + 1] *= sqrt((
double)count_nonzero / (
double)(ilastnonzero - ifirstnonzero));
572 void Tools::NormalTimeOrdering(
const int n,
double* volts) {
573 double volts_temp[n];
574 for (
int i=0;i<n/2;i++) {
575 volts_temp[i]=volts[i+n/2];
576 volts_temp[i+n/2]=volts[i];
578 for (
int i=0;i<n;i++) {
579 volts[i]=volts_temp[i];
583 void Tools::reverseTimeOrdering(
const int n,
double* bitsin,
double *bitsout) {
585 for (
int i=0;i<n;i++) {
586 bits_temp[i]=bitsin[n-i-1];
588 for (
int i=0;i<n;i++) {
589 bitsout[i]=bitsin[i];
592 void Tools::reverseTimeOrdering(
const int n,
int* bitsin,
int *bitsout) {
594 for (
int i=0;i<n;i++) {
595 bits_temp[i]=bitsin[n-i-1];
597 for (
int i=0;i<n;i++) {
598 bitsout[i]=bitsin[i];
603 int Tools::findIndex(
double *freqlab,
double freq,
int npoints,
double min,
double max) {
609 if (freq>=min && freq<freqlab[1])
611 if (freq>=freqlab[npoints-1] && freq<max)
613 return ((
int)((freq-freqlab[0])/(freqlab[1]-freqlab[0])))+1;
619 void Tools::get_random_rician(
double signal_amplitude,
double signal_phase,
double sigma,
double &litude,
double &phase){
620 double rand_gauss_a, rand_gauss_b;
621 get_circular_bivariate_normal_random_variable(rand_gauss_a, rand_gauss_b);
624 rand_gauss_a *= sigma;
625 rand_gauss_b *= sigma;
628 rand_gauss_a += signal_amplitude * cos(signal_phase);
629 rand_gauss_b += signal_amplitude * sin(signal_phase);
632 amplitude = sqrt(rand_gauss_a * rand_gauss_a + rand_gauss_b * rand_gauss_b);
634 phase = atan2(rand_gauss_b, rand_gauss_a);
639 void Tools::get_circular_bivariate_normal_random_variable(
double& rand_gauss_a,
double& rand_gauss_b){
640 TRandom * rng =getRNG(RNG_RICIAN);
642 double rand_uni_a = rng->Rndm();
643 double rand_uni_b = rng->Rndm();
644 double first_term = sqrt(-2. * log(rand_uni_a));
646 rand_gauss_a = first_term * cos(2. * M_PI * rand_uni_b);
647 rand_gauss_b = first_term * sin(2. * M_PI * rand_uni_b);
652 int Tools::round(
double number){
653 return (number > 0.0) ? floor(number + 0.5) : ceil(number - 0.5);
657 double Tools::AbbyPhiCalc(
double x_abby,
double y_abby){
658 double abbyanglephi = 0;
660 if(x_abby>=0 && y_abby>=0)
661 abbyanglephi= atan(y_abby/x_abby)*DEGRAD;
662 if(x_abby<0 && y_abby>=0)
663 abbyanglephi= atan(y_abby/x_abby)*DEGRAD+180.;
664 if(x_abby<0 && y_abby<0)
665 abbyanglephi= atan(y_abby/x_abby)*DEGRAD+180.;
666 if(x_abby>=0 && y_abby<0)
667 abbyanglephi= atan(y_abby/x_abby)*DEGRAD+360.;
669 if(x_abby==0 && y_abby>=0)
671 if(x_abby==0 && y_abby<=0)
677 TGraph *Tools::getInterpolatedGraph(TGraph *grIn, Double_t deltaT)
680 std::vector<double> tVec;
681 std::vector<double> vVec;
683 Int_t numIn=grIn->GetN();
686 Double_t startTime=0;
688 for (
int samp=0;samp<numIn;samp++) {
689 grIn->GetPoint(samp,tIn,vIn);
698 std::cout <<
"Insufficent points for interpolation\n";
703 ROOT::Math::Interpolator chanInterp(tVec,vVec,ROOT::Math::Interpolation::kAKIMA);
705 Int_t roughPoints=Int_t((lastTime-startTime)/deltaT);
708 Double_t *newTimes =
new Double_t[roughPoints+100];
709 Double_t *newVolts =
new Double_t[roughPoints+100];
711 for(Double_t time=startTime;time<=lastTime;time+=deltaT) {
712 newTimes[numPoints]=time;
713 newVolts[numPoints]=chanInterp.Eval(time);
720 TGraph *grInt =
new TGraph(numPoints,newTimes,newVolts);
728 double Tools::calculateSNR(
double justSig[512],
double justNoise[512]){
730 double p2p = Tools::dMax(justSig, 512) - Tools::dMin(justSig, 512) ;
733 for (
int i=0; i<256; i++){
734 rms += justNoise[i]*justNoise[i];
738 rms=TMath::Sqrt(rms);
748 double *left,
double *right) {
756 double hvolts_f[nfour/2];
757 double vvolts_f[nfour/2];
758 for (
int i=0;i<nfour/2;i++) {
759 hvolts_f[i]=hvolts[i];
760 vvolts_f[i]=vvolts[i];
763 realft(hvolts_f,1,nfour/2);
764 realft(vvolts_f,1,nfour/2);
766 for (
int i=0;i<nfour/4;i++) {
767 right[2*i]=1/sqrt(2.)*(vvolts_f[2*i]-hvolts_f[2*i+1]);
768 left[2*i]=1/sqrt(2.)*(hvolts_f[2*i]-vvolts_f[2*i+1]);
770 right[2*i+1]=1/sqrt(2.)*(vvolts_f[2*i+1]+hvolts_f[2*i]);
771 left[2*i+1]=1/sqrt(2.)*(hvolts_f[2*i+1]+vvolts_f[2*i]);
774 left[2*i]=left[2*i]*2./((double)nfour/2.);
775 left[2*i+1]=left[2*i+1]*2./((double)nfour/2.);
777 right[2*i]=right[2*i]*2./((double)nfour/2.);
778 right[2*i+1]=right[2*i+1]*2./((double)nfour/2.);
781 realft(left,-1,nfour/2);
782 realft(right,-1,nfour/2);