From b90bba9aa13f594ea65f90bc29334c05c2bfbda7 Mon Sep 17 00:00:00 2001 From: Hernan Asorey <asoreyh@gmail.com> Date: Wed, 31 Dec 2014 00:12:32 -0500 Subject: [PATCH] sol.cc now fit muon hump and other features to identify muon and other bands. At this commit, waiting for Yunior to test on one month of data --- sol.cc | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 2 deletions(-) diff --git a/sol.cc b/sol.cc index 842d0f7..bd3eed8 100644 --- a/sol.cc +++ b/sol.cc @@ -68,6 +68,32 @@ double itpl_chr(double *pos_avg, double *chr_avg, int i, double x) { return (y0 + (y1 - y0) * (x - x0) / (x1 - x0)); } +double fitHisto(int xi, int xf, int* h, double* r) { + double y1, x1, x2, x3, x4, xy, x2y, x, y, v1, v2, v; + v = v1 = v2 = x = y = y1 = x1 = x2 = x3 = x4 = xy = x2y = 0.0; + int n = 0; + for (int i = xi; i <= xf; i++) { + x = i; + y = (double) h[i]; + x1 += x; + y1 += y; + xy += x * y; + x *= i; + x2 += x; + x2y += x * y; + x *= i; + x3 += x; + x *= i; + x4 += x; + n++; + } + v1 = x1 * x2 * x2y - n * x2y * x3 - x2 * x2 * xy + n * x4 * xy + x2 * x3 * y1 - x1 * x4 * y1; + v2 = x1 * x1 * x2y - n * x2 * x2y + n * x3 * xy + x2 * x2 * y1 - x1 * (x2 * xy + x3 * y1); + v = v1 / (2.0 * v2); // note v1 = -a1 and v2 = a2, so we have v = -b / 2a ! + *r = y1; + return v; +} + void Usage(char *prog) { cout << endl << PROJECT << " " << VERSION << endl; cout << endl << "This is the Space Weather dedicated analysis (L1 -> L2SW)" << endl<< endl; @@ -180,7 +206,7 @@ int main (int argc, char *argv[]) { /* preparing outputs */ char *ifile2; - char ifile[256]; + char ifile[256], ifile0[256]; ifile2=ifiname; if (strrchr(ifile2,'/')!=NULL) ifile2=strrchr(ifile2,'/')+1; // remove dirs if present @@ -191,6 +217,7 @@ int main (int argc, char *argv[]) { if (strrchr(ifile,'.')!=NULL) if (strncmp(strrchr(ifile,'.'),".sol",4)==0) // remove .sol if present *(strrchr(ifile,'.'))='\0'; + strcpy(ifile0,ifile); if (strncmp(ifile,"l1_",3)==0) { *(strchr(ifile,'1'))='2'; // change l1 by l2 } @@ -199,7 +226,6 @@ int main (int argc, char *argv[]) { Usage(argv[0]); } - /* end of preparing outputs */ /* preparing for work */ @@ -275,7 +301,119 @@ int main (int argc, char *argv[]) { char line[16384]; double fluxband[nbands]; int currentpos=0, pos=0, i=0, is=0, j=0,k=0; + /// New analysis done by Y. Perez and H. Asorey + ///// Obtain muon charge and other features from cal histogram + ///// and use them for determining bands of interest + ///// underway: mar dic 30 23:38:56 COT 2014 + /* now, we have to read calibration (1h) histogram from ifile.cal, so: + * trying to open histogram file + */ + snprintf(nfi,256,"%s.cal",ifile0); + if ((cal = fopen(nfi,"r"))==NULL) { + fprintf(stderr,"\nError: Failed to open calibration histogram file (%s). Abort.\n",nfi); + exit(1); + } + /* read the histogram */ + fprintf(stderr,"Reading calibration histogram %s\n",nfi); + int p[3], c[3], charge[maxcharge]; + int cline=0, ncharge=0; + while(fgets(line, 16384,cal)) { + cline++; + if (line[0] == '#') // comments? meta-data? for now, just skipping + continue; + if (cline < 1028) { + do { // read + check=sscanf(line, "%d %d %d %d %d %d\n", &c[0], &c[1], &c[2], &p[0], &p[1], &p[2]); + } while (check != 6); + } + else { + do { // read + check=sscanf(line, "%d %d %d\n", &c[0], &c[1], &c[2]); + } while (check != 3); + } + if (ncharge>maxcharge) + fprintf(stderr,"Warning: Too long charge histogram. It has %d lines (expected lines = %d)\n", ncharge, maxcharge); + charge[ncharge] = c[channel]; + ncharge++; + } + fclose(cal); + /* now, charge[] has the charge histogram for the analyzed channel + * average it!, but, graded + */ + int l1 = 200; /* Yunior used this cut . If charge < l1, ds=6; else ds = 25 + * I put ds=5 as a multiple of l1 + */ + int sum = 0, cnt_avg=0; + double chr_avg[maxcharge], pos_avg[maxcharge]; + for (i=0; i<maxcharge; i++) + chr_avg[i] = pos_avg[i] = 0.; + int step=0; + /* low energy */ + step=5; + for (i=0; i<l1; i+=step) { + sum = 0; + for (j=0; j<step; j++) + sum += charge[i+j]; + chr_avg[cnt_avg]=sum/step; + pos_avg[cnt_avg]=i+step/2.; + cnt_avg++; + } + /* high energy */ + step=50; + for (i=l1; i<maxcharge; i+=step) { + sum = 0; + for (j=0; j<step; j++) + sum += charge[i+j]; + chr_avg[cnt_avg]=sum/step; + pos_avg[cnt_avg]=i+step/2.; + cnt_avg++; + } + /* Histogram are averaged. Now, derive it! */ + cnt_avg-=2; //avoid last average point because it's usally too noise + double chr_der[cnt_avg]; + for (i=0; i<cnt_avg; i++) //taking logs to magnify the effect (thanks Mauricio Suarez) + chr_der[i] = ((log10(chr_avg[i+1])-log10(chr_avg[i]))/(pos_avg[i+1]-pos_avg[i])); + // looking for 0s on histogram derivative... + double zeros[cnt_avg], zeros_pos[cnt_avg]; + int cnt_zeros=0; + for (i=0; i<cnt_avg; i++) + zeros_pos[i]=zeros[i]=0.; + for (i=0; i<cnt_avg-1; i++) { + if (!sign(chr_der[i])) { // bingo... too good to be true + zeros_pos[cnt_zeros]=(double) i; + zeros[cnt_zeros]=chr_avg[i]; // charge + cnt_zeros++; + } + else if (sign(chr_der[i+1]) != sign(chr_der[i])) { // Bolzano's theorem!! + zeros_pos[cnt_zeros]=itpl_pos(pos_avg, chr_der,i); + zeros[cnt_zeros]=itpl_chr(pos_avg, chr_avg, i, zeros_pos[cnt_zeros]); + cnt_zeros++; + } + } + /* So, we have the histogram seeds, let's fit them */ + double tmpk=0.; + double feat[3]; + // TODO erase this block, only for debbuging of fitting procedure + snprintf(nfi,256,"%s.pos",ifile); + FILE *pof; + if ((pof = fopen(nfi,"w"))==NULL) { + fprintf(stderr,"\nError: Failed to open pos file. Abort.\n"); + exit(1); + } + // + + for (i=0; i<3; i++) { + feat[i] = fitHisto(int(zeros_pos[i]*0.9), int(zeros_pos[i]*1.3), charge, &tmpk); + // TODO erase this block, only for debbuging of fitting procedure + do { + check=fprintf(pof, "%d %.3f %.3f\n", i, zeros_pos[i], feat[i]); + } while (check<=0); + } + /* and done. We found the EM peak, the transition to hump, and the muon hump + * of the calibration histogram, in charge units =D + */ + /////// HERE ENDS THE NEW BLOCK - WAITING FOR YUNIOR TESTS ON DATA TO INCLUDE /* analyze the .sol histograms */ while(fgets(line, 16384,fi)) { @@ -341,4 +479,6 @@ int main (int argc, char *argv[]) { pclose(out); else fclose(out); + // TODO erase this block, only for debbuging of fitting procedure + fclose(pof); } -- GitLab