/* Test harness routine, which contains test quadratic data, invokes mpfit() */ int testquadfit() { double x[] = {-1.7237128E+00,1.8712276E+00,-9.6608055E-01, -2.8394297E-01,1.3416969E+00,1.3757038E+00, -1.3703436E+00,4.2581975E-02,-1.4970151E-01, 8.2065094E-01}; double y[] = {2.3095947E+01,2.6449392E+01,1.0204468E+01, 5.40507,1.5787588E+01,1.6520903E+01, 1.5971818E+01,4.7668524E+00,4.9337711E+00, 8.7348375E+00}; double ey[10]; double p[] = {1.0, 1.0, 1.0}; /* Initial conditions */ double pactual[] = {4.7, 0.0, 6.2}; /* Actual values used to make data */ double perror[3]; /* Returned parameter errors */ int i; struct vars_struct v; int status; mp_result result; memset(&result,0,sizeof(result)); /* Zero results structure */ result.xerror = perror; for (i=0; i<10; i++) ey[i] = 0.2; /* Data errors */ v.x = x; v.y = y; v.ey = ey; /* Call fitting function for 10 data points and 3 parameters */ status = mpfit(quadfunc, 10, 3, p, 0, 0, (void *) &v, &result); printf("*** testquadfit status = %d\n", status); printresult(p, pactual, &result); return 0; }
/* Test harness routine, which contains test data, invokes mpfit() */ int testfit() { int j, k = 0; FILE *data; FILE *output; data = fopen("Compiled_Data.txt", "r"); output = fopen("Constants.ini", "w"); int n; fscanf(data, "%d", &n); double p[4]; double x[820][2]; double y[820]; for (j = 0; j < n; j++) { fscanf(data, "%lf", &p[j]); } while (fscanf(data, "%lf,%lf,%lf", &x[k][0], &x[k][1], &y[k]) != EOF) { k++; } int i; struct vars_struct v; int status; mp_result result; mp_par constraints[4]; memset(&result, 0, sizeof(result)); /* Zero results structure and parameter constraints */ memset(constraints, 0, sizeof(constraints)); for (i = 0; i < n / 2; i++) { constraints[2 * i].limited[0] = 1; constraints[2 * i].limited[1] = 1; constraints[2 * i].limits[0] = 0.0; constraints[2 * i].limits[1] = 100.0; } v.x = x; v.y = y; /* Call fitting function for 820 data points and 4 (n) parameters */ status = mpfit(statfunc, 820, n, p, constraints, 0, (void *)&v, &result); fprintf(output, "*** testfit status = %d (Editing this file is not recommended)\n", status); for(i = 0; i < n; i++) { if (i % 2 == 0) { fprintf(output, "Maximum %d = %lf\n", i / 2, p[i]); } else { fprintf(output, "Weight %d = %lf\n", i / 2, p[i]); } } //printresult(p, &result); return 0; }
/* Test harness routine, which contains test gaussian-peak data Example of fixing two parameter Commented example of how to put boundary constraints */ int testgaussfix() { double x[] = {-1.7237128E+00,1.8712276E+00,-9.6608055E-01, -2.8394297E-01,1.3416969E+00,1.3757038E+00, -1.3703436E+00,4.2581975E-02,-1.4970151E-01, 8.2065094E-01}; double y[] = {-4.4494256E-02,8.7324673E-01,7.4443483E-01, 4.7631559E+00,1.7187297E-01,1.1639182E-01, 1.5646480E+00,5.2322268E+00,4.2543168E+00, 6.2792623E-01}; double ey[10]; double p[] = {0.0, 1.0, 0.0, 0.1}; /* Initial conditions */ double pactual[] = {0.0, 4.70, 0.0, 0.5};/* Actual values used to make data*/ double perror[4]; /* Returned parameter errors */ mp_par pars[4]; /* Parameter constraints */ int i; struct vars_struct v; int status; mp_result result; memset(&result,0,sizeof(result)); /* Zero results structure */ result.xerror = perror; memset(pars,0,sizeof(pars)); /* Initialize constraint structure */ pars[0].fixed = 1; /* Fix parameters 0 and 2 */ pars[2].fixed = 1; /* How to put limits on a parameter. In this case, parameter 3 is limited to be between -0.3 and +0.2. pars[3].limited[0] = 0; pars[3].limited[1] = 1; pars[3].limits[0] = -0.3; pars[3].limits[1] = +0.2; */ for (i=0; i<10; i++) ey[i] = 0.5; v.x = x; v.y = y; v.ey = ey; /* Call fitting function for 10 data points and 4 parameters (2 parameters fixed) */ status = mpfit(gaussfunc, 10, 4, p, pars, 0, (void *) &v, &result); printf("*** testgaussfix status = %d\n", status); printresult(p, pactual, &result); return 0; }
int mp_nllsqfit( real *xdat, /* x[ndat][xdim] or x(xdim,ndat) */ int xdim, /* */ real *ydat, /* y[ndat] */ real *wdat, /* w[ndat] */ real *ddat, /* d[ndat] */ int ndat, /* */ real *fpar, /* f[npar] */ real *epar, /* e[npar] */ int *mpar, /* m[npar] */ int npar, /* */ real tol, /* tolerance to convergence */ int its, /* # iterations */ real lab, /* (small) mixing parameter (0 for linear) */ rproc f, /* f */ iproc df) /* df/da */ { float *x, *y, *sig, **covar, **alpha; float *a, chisq, ochisq, lamda, fac; int i, k, itst, *ia; int itc = 0; mp_config *config = NULL; mp_par *pars = NULL; void *private_data = NULL; mp_result result; if (npar > MAXPAR) error("MAXPAR too small for npar"); if (xdim > MAXPAR) error("MAXPAR too small for xdim"); if (xdim != 1) error("mp_nllsqfit: cannot deal with xdim=%d",xdim); old_f = f; /* mpfit only uses f, doesn't need df */ mpfit(my_func, ndat, npar, xdat, pars, config, private_data, &result); /* to be called as follows: */ // funct(m,n,x,fvec,dvec,priv); return 0; /* return number of iterations */ }
/* Test harness routine, which contains test data, invokes mpfit() */ int testlinfit() { double x[] = {-1.7237128E+00,1.8712276E+00,-9.6608055E-01, -2.8394297E-01,1.3416969E+00,1.3757038E+00, -1.3703436E+00,4.2581975E-02,-1.4970151E-01, 8.2065094E-01}; double y[] = {1.9000429E-01,6.5807428E+00,1.4582725E+00, 2.7270851E+00,5.5969253E+00,5.6249280E+00, 0.787615,3.2599759E+00,2.9771762E+00, 4.5936475E+00}; double ey[10]; /* y = a - b*x */ /* a b */ double p[2] = {1.0, 1.0}; /* Parameter initial conditions */ double pactual[2] = {3.20, 1.78}; /* Actual values used to make data */ double perror[2]; /* Returned parameter errors */ int i; struct vars_struct v; int status; mp_result result; memset(&result,0,sizeof(result)); /* Zero results structure */ result.xerror = perror; for (i=0; i<10; i++) ey[i] = 0.07; /* Data errors */ v.x = x; v.y = y; v.ey = ey; /* Call fitting function for 10 data points and 2 parameters */ status = mpfit(linfunc, 10, 2, p, 0, 0, (void *) &v, &result); printf("*** testlinfit status = %d\n", status); printresult(p, pactual, &result); return 0; }
do_line() { real *x, *y, *dx, *dy, *dz; int i,j, mwt; real chi2,q,siga,sigb, sigma, d, sa, sb; real cov00, cov01, cov11, sumsq; real r, prob, z; void fit(), pearsn(); if (nxcol < 1) error("nxcol=%d",nxcol); if (nycol < 1) error("nycol=%d",nycol); x = xcol[0].dat; y = ycol[0].dat; dx = (dxcolnr>0 ? dxcol.dat : NULL); dy = (dycolnr>0 ? dycol.dat : NULL); #if HAVE_GSL if (dx) error("Cannot use GSL with errors in X column"); gsl_fit_linear (x, 1, y, 1, npt, &b, &a, &cov00, &cov01, &cov11, &sumsq); printf("y=ax+b: a=%g b=%g cov00,01,11=%g %g %g sumsq=%g\n", a,b, cov00,cov01,cov11, sumsq); if (dy) { for (i=0; i<npt; i++) dy[i] = 1/(dy[i]*dy[i]); gsl_fit_wlinear (x, 1, dy, 1, y, 1, npt, &b, &a, &cov00, &cov01, &cov11, &chi2); printf("y=ax+b: a=%g b=%g cov00,01,11=%g %g %g chi^2=%g\n", a,b, cov00,cov01,cov11, chi2); } #else if (dx) { #if defined(TESTNR) warning("new FITEXY method"); dz = (real *) allocate(npt*sizeof(real)); for (i=0; i<npt; i++) dz[i] = 0.0; fitexy(x,y,npt,dx,dy,&b,&a,&sigb,&siga,&chi2,&q); printf("fitexy(x,y,dx,dy) a=%g b=%g %g %g\n",b,a,sigb,siga); fitexy(x,y,npt,dz,dy,&a,&b,&siga,&sigb,&chi2,&q); printf("fitexy(x,y, 0,dy) a=%g b=%g %g %g\n",a,b,siga,sigb); fitexy(x,y,npt,dx,dz,&a,&b,&siga,&sigb,&chi2,&q); printf("fitexy(x,y,dx, 0) a=%g b=%g %g %g\n",a,b,siga,sigb); fit (x,y,npt,dy, 1,&a,&b,&siga,&sigb,&chi2,&q); printf("fit (x,y, 0,dy) a=%g b=%g %g %g\n",a,b,siga,sigb); fit (y,x,npt,dx, 1,&a,&b,&siga,&sigb,&chi2,&q); printf("fit (y,x, 0,dx) a=%g b=%g %g %g\n",a,b,siga,sigb); sa=sqrt(siga*siga+sqr(sigb*(a/b)))/b; sb=sigb/(b*b); printf("FITEXY: %11.6f %11.6f %11.6f %11.6f %11.6f %11.6f\n", -a/b,1.0/b,sa,sb,chi2,q); #elif defined(TESTMP) struct vars_struct v; /* private data for mpfit() */ int status; mp_result result; double p[2] = {1.0, 1.0}; double perror[2]; warning("MPFIT method; mode mpfit=%d",mpfit_mode); bzero(&result,sizeof(result)); result.xerror = perror; v.x = xcol[0].dat; v.y = ycol[0].dat; v.ex = dxcol.dat; v.ey = dycol.dat; v.mode = mpfit_mode; status = mpfit(linfitex, npt, 2, p, 0, 0, (void *) &v, &result); dprintf(1,"*** mpfit status = %d\n", status); printf(" CHI-SQUARE = %f (%d DOF)\n", result.bestnorm, result.nfunc-result.nfree); printf(" NPAR = %d\n", result.npar); printf(" NFREE = %d\n", result.nfree); printf(" NPEGGED = %d\n", result.npegged); printf(" NITER = %d\n", result.niter); printf(" NFEV = %d\n", result.nfev); printf("\n"); for (i=0; i<result.npar; i++) { printf(" P[%d] = %f +/- %f\n", i, p[i], result.xerror[i]); } #else error("no dycol= implemented yet"); #endif } else { for(mwt=0;mwt<=1;mwt++) { #if 1 if (mwt>0 && nsigma>0) { fit(x,y,npt,dy,0,&b,&a,&sigb,&siga,&chi2,&q); } else { if (mwt>0 && dycolnr==0) continue; fit(x,y,npt,dy,mwt,&b,&a,&sigb,&siga,&chi2,&q); } #else if (mwt==0) fit(x,y,npt,dy,mwt,&b,&a,&sigb,&siga,&chi2,&q); else myfit(x,y,npt,dy,mwt,&b,&a,&sigb,&siga,&chi2,&q); #endif dprintf(2,"\n"); dprintf (1,"Fit: y=ax+b\n"); if (mwt == 0) dprintf(1,"Ignoring standard deviations\n"); else dprintf(1,"Including standard deviation\n"); printf("%12s %9.6f %18s %9.6f \n", "a = ",a,"uncertainty:",siga); printf("%12s %9.6f %18s %9.6f \n", "b = ",b,"uncertainty:",sigb); printf("%12s %9.6f %18s %9.6f \n", "x0 = ",-b/a,"uncertainty:",sqrt(sqr(sigb/a)+sqr(siga*b/(a*a)))); printf("%12s %9.6f %18s %9.6f \n", "y0 = ",b,"uncertainty:",sigb); printf("%19s %14.6f \n","chi-squared: ",chi2); printf("%23s %10.6f %s\n","goodness-of-fit: ",q, q==1 ? "(no Y errors supplied [dycol=])" : ""); pearsn(x, y, npt, &r, &prob, &z); printf("%9s %g\n","r: ",r); printf("%12s %g\n","prob: ",prob); printf("%9s %g\n","z: ",z); if (mwt==0 && nsigma>0) { sigma = 0.0; for(i=0; i<npt; i++) sigma += sqr(y[i] - a*x[i] - b); sigma /= (real) npt; sigma = nsigma * sqrt(sigma); /* critical distance */ for(i=0, j=0; i<npt; i++) { /* loop over points */ d = ABS(y[i] - a*x[i] - b); if (d > sigma) continue; x[j] = x[i]; /* shift them over */ y[j] = y[i]; if (dy) dy[j] = dy[i]; j++; } dprintf(0,"%d/%d points outside %g*sigma (%g)\n", npt-j,npt,nsigma,sigma); npt = j; } } /* mwt */ } /* dxcol */ if (outstr) write_data(outstr); #endif }
int DoIt(){ /* Variable declarations */ /* Generic use variables */ int i,j,k,l,n; /* Generic loop counters */ /* DRMS/JSOC variables */ char *harpnum,*time_range; /* SHARPs ID and time range from module_args[] */ double umb_sig, pen_sig; /* Cutoffs for sunspots */ int num_divs; /* Number of divisions to break a data strip into for trend removal */ char *drms_query; /* The DRMS query we are going to send */ int num_query_chars; /* Number of characters in total query for malloc definition */ CmdParams_t *params=&cmdparams; /* For the module_args stuff */ DRMS_RecordSet_t *drms_ids; /* Holds the id structure of the records */ DRMS_Record_t *drms_record; /* Holds specific record information */ DRMS_Segment_t *drms_segment; /* Segment information */ int drms_status; /* Status variable */ int num_records; /* Number of records and variables to get the segment locations we need */ /* cfitsio-related variables */ fitsfile *v_ptr,*i_ptr,*c_ptr; /* Pointers for FITS files */ fitsfile *info_ptr; int v_status,i_status,c_status; /* Status checker for opening files */ int info_status; int hdu_pos,num_hdus; /* HDU number and location */ int needed_hdu; /* The HDU we want to be on */ int any_nulls; /* Nonzero if there are null values in data */ char i_filename[DRMS_MAXPATHLEN+1],v_filename[DRMS_MAXPATHLEN+1]; /* Containers for the filenames */ char c_filename[DRMS_MAXPATHLEN+1],info_filename[DRMS_MAXPATHLEN+1]; double nulval; /* Container for what null values in data should be set to */ long l_nulval; /* Needed FITS keywords */ int naxis1,naxis2,naxis; /* Length of axes */ double crpix1,crpix2; /* SHARPs CRPIX is the center of the Sun relative to the lower left of the patch (fortranL 1,1) */ double imcrpix1,imcrpix2; /* SHARPs IMCRPIX is the center of the Sun in full plate coordinates (fortran) */ double cdelt1,cdelt2; /* HMI pixel sizes in as */ double blank; /* Values of bad data */ double crota2,crln_obs,crlt_obs; /* Rotation, carrington observer location */ double dsun_obs,rsun_obs; /* Distance to and radius of the sun, observed at t_obs */ double obs_vr,obs_vw,obs_vn; /* Satellite velocity keywords */ TIME t_obs; /* Observation time, ZULU */ char **t_obs_s; /* String version of observation time */ long *quality; /* Data quality keyword */ /* Data-related variables */ double **vlos_dat, **inc_dat; /* Data arrays, size defined once naxis1/2 are known */ double **con_dat; long **info_dat; double *v_pixel_strip; /* Strip of pixels read from the field data */ double *i_pixel_strip; /* Strip of pixels read from the inclination data */ double *c_pixel_strip; /* Strip of pixels read from the continuum data */ long *info_pixel_strip; /* Strip of pixels read from the continuum data */ long fpixel[2]; /* Holds the location of pixel to be read */ LONGLONG nelements; /* Number of elements in a strip to be read (naxis2) */ FILE *outptr,*bad_outptr; /* Pointer to the outfile */ char outfile_name[25]; /* Name of the outfile */ char bad_outfile_name[24]; /* Name of the outfile for bad quality*/ /* Variables related to the actual task */ double rscx,rscy; /* Disk center, plate coordinates */ double rllx,rlly; /* Disk center, patch coordinates */ double rpllx,rplly; /* Lower left of patch, plate coordinates */ double **radius; /* Array to hold where the Sun's boundaries are, column major order */ double umb,pen; /* Intensity cutoffs for the umbra and penumbra */ double num_good; /* The number of nonzero continuum values in a sunspot region */ double mu; /* Angle from solar center */ double rsun_pix,xx,yy,r; /* Variables associated with radial boundaries */ long *t_secs; /* T_OBS time converted to seconds since UNIX epoch */ double *umb_p_vel,*umb_n_vel; /* Umbral LOS velocities */ double *pen_p_vel,*pen_n_vel; /* Penumbral LOS velocities */ double umb_p_counter,umb_n_counter; /* Counters for averages */ double pen_p_counter,pen_n_counter; double vr,vn,vw,vt; /* Various LOS velocities due to satellite motion and solar rotation */ double vlos; /* VLOS after removing all of the satellite motion and solar rotation */ double **y_axis; /* Array to be looped over wrt naxis2 to remove trends */ double **y_error; /* Error on y axis, taken as 1 */ double **x_axis; /* Array to be looped over that holds naxis1 information for fitting */ double x,y; /* Pixel location on the solar disk */ double ttx,tty,tx,ty,zz; /* Intermediate variables for coordinate conversions */ double lat,lon; /* Carrington coordinate latitude and longitude */ double p,t; /* Spherical phi and theta coordinates */ int noaa_ar; /* Active region number */ mp_result result; /* Fitting result structure */ mp_config config; /* Configuration options for fitting structure */ double perror[2]; /* Error on fitting coefficients */ double fit_params[2]; /* Fitting coefficients */ struct vars_struct v; /* Private data, shared between main and functions */ int fit_status; /* Fitting returned status */ int inv_len; /* Interval length for breaking data up */ /* Initialise variables that need it */ drms_status=0; memset(&result,0,sizeof(result)); memset(&config,0,sizeof(config)); /* Set the error stuff for cmfit */ result.xerror=perror; /* Set the default options for cmfit */ config.ftol=1.49012e-08; config.xtol=1.49012e-08; config.gtol=0.0; config.maxfev=0; /* Grab values from module_args[] */ harpnum=strdup(params_get_str(params,"harpnum")); time_range=strdup(params_get_str(params,"time_range")); umb_sig=params_get_double(params,"umb_sig"); pen_sig=params_get_double(params,"pen_sig"); num_divs=params_get_int(params,"num_divs"); /* Now we start the main program. The rough layout is as follows: 1. Query drms. Based on what we learn, either exit or grab what we need from it. 2. Loop through the files, calculate field stuff. 3. Print out a table of values at the end. */ /* Forge the DRMS query. */ num_query_chars=16+strlen(harpnum); /* hmi.sharp_720s[] is 16 characters */ if (time_range!="[]"){ num_query_chars+=strlen(time_range); } drms_query=calloc(num_query_chars,sizeof(char)); strcat(drms_query,"hmi.sharp_720s["); strcat(drms_query,harpnum); strcat(drms_query,"]"); if (time_range!="[]"){ strcat(drms_query,time_range); } /* Query DRMS for the records. */ printf("Querying DRMS. This may take some time.\n"); if (!(drms_ids=drms_open_records(drms_env,drms_query,&drms_status))){ printf("No record sets match your criteria. Check your SHARPs ID and your time range.\n"); drms_close_records(drms_ids,DRMS_FREE_RECORD); free(drms_query); return 0; } free(drms_query); num_records=drms_ids->n; printf("%d records match. Checking to make sure we have the needed data segments.\n",num_records); drms_record=drms_ids->records[0]; if (!(drms_segment_lookup(drms_record,"vlos_mag"))){ printf("vlos_mag segment not present! Exiting.\n"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(drms_segment_lookup(drms_record,"inclination"))){ printf("Inclination segment not present! Exiting.\n"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(drms_segment_lookup(drms_record,"continuum"))){ printf("Continuum segment not present! Exiting.\n"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(drms_segment_lookup(drms_record,"info_map"))){ printf("Info_map segment not present! Exiting.\n"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } /* Now we can start. We loop over all records, get the keyword information we need, get the data, and then calculate. */ /* First set the size of some of the pointers that are intended to be arrays. */ /* Time-related arrays */ t_secs=malloc(num_records*sizeof(long)); t_obs_s=malloc(num_records*sizeof(char *)); for (i=0;i<num_records;i++){ t_obs_s[i]=malloc(T_OBS_LENGTH*sizeof(char)); } /* Data-related arrays */ umb_p_vel=malloc(num_records*sizeof(double)); pen_p_vel=malloc(num_records*sizeof(double)); umb_n_vel=malloc(num_records*sizeof(double)); pen_n_vel=malloc(num_records*sizeof(double)); /* Record quality */ quality=malloc(num_records*sizeof(long)); for (k=0;k<num_records;k++){ drms_record=drms_ids->records[k]; /* Check to see if we have data for a particular observation time */ if (!(t_obs=drms_getkey_time(drms_record,"T_OBS",&drms_status))){ printf("Keyword %s not present! Exiting.\n","T_OBS"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (time_is_invalid(t_obs)){ printf("Bad record, skipping.\n"); } else { if (k == 0){ /* Get active region number for pregame info */ if (!(noaa_ar=drms_getkey_int(drms_record,"NOAA_AR",&drms_status))){ printf("Keyword %s not present! Exiting.\n","NOAA_AR"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } /* Create data output filename */ sprintf(outfile_name,"AR%d.fvlos-output.dat",noaa_ar); sprintf(bad_outfile_name,"AR%d.bad-quality.dat",noaa_ar); /* Print out some stats before we run */ printf("Pre-analysis details:\n"); printf("Analyzing: HARP Number: %s\t NOAA AR: %d\n",harpnum,noaa_ar); printf("Output file: %s\n",outfile_name); if (time_range == "[]\0"){ printf("We are covering the entire data set.\n"); } else { printf("Time range: %s\n",time_range); } printf("\n\n"); } printf("Processing record %d of %d.\n",k+1,num_records); /* Fill keywords */ if (!(quality[k]=drms_getkey_longlong(drms_record,"QUALITY",&drms_status))){ quality[k]=0; } if (!(crpix1=drms_getkey_double(drms_record,"CRPIX1",&drms_status))){ printf("Keyword %s not present! Exiting.\n","CRPIX1"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(crpix2=drms_getkey_double(drms_record,"CRPIX2",&drms_status))){ printf("Keyword %s not present! Exiting.\n","CRPIX2"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(cdelt1=drms_getkey_double(drms_record,"CDELT1",&drms_status))){ printf("Keyword %s not present! Exiting.\n","CDELT1"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(cdelt2=drms_getkey_double(drms_record,"CDELT2",&drms_status))){ printf("Keyword %s not present! Exiting.\n","CDELT2"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(imcrpix1=drms_getkey_double(drms_record,"IMCRPIX1",&drms_status))){ printf("Keyword %s not present! Exiting.\n","IMCRPIX1"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(imcrpix2=drms_getkey_double(drms_record,"IMCRPIX2",&drms_status))){ printf("Keyword %s not present! Exiting.\n","IMCRPIX2"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(rsun_obs=drms_getkey_double(drms_record,"RSUN_OBS",&drms_status))){ printf("Keyword %s not present! Exiting.\n","RSUN_OBS"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(dsun_obs=drms_getkey_double(drms_record,"DSUN_OBS",&drms_status))){ printf("Keyword %s not present! Exiting.\n","DSUN_OBS"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(obs_vr=drms_getkey_double(drms_record,"OBS_VR",&drms_status))){ printf("Keyword %s not present! Exiting.\n","OBS_VR"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(obs_vn=drms_getkey_double(drms_record,"OBS_VN",&drms_status))){ printf("Keyword %s not present! Exiting.\n","OBS_VN"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(obs_vw=drms_getkey_double(drms_record,"OBS_VW",&drms_status))){ printf("Keyword %s not present! Exiting.\n","OBS_VW"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(crota2=drms_getkey_double(drms_record,"CROTA2",&drms_status))){ printf("Keyword %s not present! Exiting.\n","CROTA2"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(crln_obs=drms_getkey_double(drms_record,"CRLN_OBS",&drms_status))){ printf("Keyword %s not present! Exiting.\n","CRLN_OBS"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(crlt_obs=drms_getkey_double(drms_record,"CRLT_OBS",&drms_status))){ printf("Keyword %s not present! Exiting.\n","CRLT_OBS"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } if (!(blank=drms_getkey_double(drms_record,"BLANK",&drms_status))){ printf("Keyword %s not present! Exiting.\n","BLANK"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } sprint_ut(t_obs_s[k],t_obs); /* Convert to string */ printf(" Checking quality.\n"); if (quality[k] == 0){ /* Ok, now we get the file locations for the data from DRMS. Originally I attempted * to pull the data directly from DRMS but there were vague free() and malloc() issues * possibly due to icc and multithreading, or library problems. */ if (!(drms_segment=drms_segment_lookup(drms_record,"vlos_mag"))){ printf("Problem opening the vlos_mag segment! Exiting.\n"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } drms_segment_filename(drms_segment,v_filename); if (!(drms_segment=drms_segment_lookup(drms_record,"continuum"))){ printf("Problem opening the continuum segment! Exiting.\n"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } drms_segment_filename(drms_segment,c_filename); /* naxis1 and naxis2 we get from segment information */ naxis1=(int)drms_segment->axis[0]; naxis2=(int)drms_segment->axis[1]; if (!(drms_segment=drms_segment_lookup(drms_record,"inclination"))){ printf("Problem opening the inclination segment! Exiting.\n"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } drms_segment_filename(drms_segment,i_filename); if (!(drms_segment=drms_segment_lookup(drms_record,"info_map"))){ printf("Problem opening the info_map segment! Exiting.\n"); drms_close_records(drms_ids,DRMS_FREE_RECORD); return 0; } drms_segment_filename(drms_segment,info_filename); printf(" Opening FITs files.\n"); /* Now open the FITS files and get to work. */ v_status=0; i_status=0; c_status=0; info_status=0; any_nulls=0; if (fits_open_file(&v_ptr,v_filename,READONLY,&v_status)){ printf("Cannot open %s! Exiting.\n",v_filename); exit(0); } if (fits_open_file(&i_ptr,i_filename,READONLY,&i_status)){ printf("Cannot open %s! Exiting.\n",i_filename); fits_close_file(i_ptr,&i_status); exit(0); } if (fits_open_file(&c_ptr,c_filename,READONLY,&c_status)){ printf("Cannot open %s! Exiting.\n",c_filename); fits_close_file(c_ptr,&c_status); exit(0); } if (fits_open_file(&info_ptr,info_filename,READONLY,&info_status)){ printf("Cannot open %s! Exiting.\n",info_filename); fits_close_file(info_ptr,&info_status); exit(0); } /* Walk through the HDUs until we get to one with NAXIS=2 */ /* Number of headers and which one we are on */ fits_get_num_hdus(v_ptr,&num_hdus,&v_status); fits_get_hdu_num(v_ptr,&hdu_pos); /* Find the one with two naxes */ naxis=0; for (i=1;i<=num_hdus;i++){ fits_movabs_hdu(v_ptr,i,NULL,&v_status); fits_read_key(v_ptr,TINT,"NAXIS",&naxis,NULL,&v_status); if (naxis == 2){ needed_hdu=i; } } /* Set all to the needed HDU */ if (naxis == 0){ printf("HDU problems: can't find one with the required number of axes.\n"); fits_close_file(v_ptr,&v_status); fits_close_file(i_ptr,&i_status); fits_close_file(c_ptr,&c_status); fits_close_file(info_ptr,&info_status); exit(0); } else { fits_movabs_hdu(v_ptr,needed_hdu,NULL,&v_status); fits_movabs_hdu(i_ptr,needed_hdu,NULL,&i_status); fits_movabs_hdu(c_ptr,needed_hdu,NULL,&c_status); fits_movabs_hdu(info_ptr,needed_hdu,NULL,&info_status); } /* Now set some definite boundaries on arrays to help with memory usage. Arrays are called as con_dat[y][x]. */ inv_len=naxis1/num_divs; vlos_dat=malloc(naxis2*sizeof(double *)); inc_dat=malloc(naxis2*sizeof(double *)); con_dat=malloc(naxis2*sizeof(double *)); radius=malloc(naxis2*sizeof(double *)); info_dat=malloc(naxis2*sizeof(long *)); y_axis=malloc(num_divs*sizeof(double *)); y_error=malloc(num_divs*sizeof(double *)); x_axis=malloc(num_divs*sizeof(double *)); v_pixel_strip=calloc(naxis1,sizeof(double)); i_pixel_strip=calloc(naxis1,sizeof(double)); c_pixel_strip=calloc(naxis1,sizeof(double)); info_pixel_strip=calloc(naxis1,sizeof(long)); for (j=0;j<naxis2;j++){ vlos_dat[j]=calloc(naxis1,sizeof(double)); inc_dat[j]=calloc(naxis1,sizeof(double)); con_dat[j]=calloc(naxis1,sizeof(double)); radius[j]=calloc(naxis1,sizeof(double)); info_dat[j]=calloc(naxis1,sizeof(long)); } for (j=0;j<(num_divs-1);j++){ x_axis[j]=calloc((inv_len),sizeof(double)); y_axis[j]=calloc((inv_len),sizeof(double)); y_error[j]=calloc((inv_len),sizeof(double)); } x_axis[num_divs-1]=calloc((inv_len + naxis1%num_divs),sizeof(double)); y_axis[num_divs-1]=calloc((inv_len + naxis1%num_divs),sizeof(double)); y_error[num_divs-1]=calloc((inv_len + naxis1%num_divs),sizeof(double)); /* Next, put data in the arrays, clear out blank values and NaNs from the data */ fpixel[0]=1; /* cfitsio uses fortran reference instead of c when accessing data */ nelements=naxis1; nulval=0; l_nulval=0; any_nulls=0; for (j=0;j<naxis2;j++){ fpixel[1]=j+1; /* Add 1 to account for fortran FITS indexing */ fits_read_pix(v_ptr,TDOUBLE,fpixel,nelements,&nulval,v_pixel_strip,&any_nulls,&v_status); fits_read_pix(i_ptr,TDOUBLE,fpixel,nelements,&nulval,i_pixel_strip,&any_nulls,&i_status); fits_read_pix(c_ptr,TDOUBLE,fpixel,nelements,&nulval,c_pixel_strip,&any_nulls,&c_status); fits_read_pix(info_ptr,TLONG,fpixel,nelements,&l_nulval,info_pixel_strip,&any_nulls,&info_status); for (i=0;i<naxis1;i++){ /* Kill blank values if present, if not assign to the correct place in array */ if (v_pixel_strip[i] == blank){ vlos_dat[j][i]=0.0; } else { vlos_dat[j][i]=v_pixel_strip[i]; } if (i_pixel_strip[i] == blank){ inc_dat[j][i]=0.0; } else { inc_dat[j][i]=i_pixel_strip[i]; } if (c_pixel_strip[i] == blank){ con_dat[j][i]=0.0; } else { con_dat[j][i]=c_pixel_strip[i]; } info_dat[j][i]=info_pixel_strip[i]; } } printf(" Analyzing data.\n"); /* Coordinate variable definitions for future use. See the declaration section */ /* at the front of the code to understand what these refer to. */ rscx=(imcrpix1-1.0); rscy=(imcrpix2-1.0); rllx=(crpix1-1.0); rlly=(crpix2-1.0); rpllx=(rscx-rllx); rplly=(rscy-rlly); /* Fill the radius array, handle limb darkening */ rsun_pix=rsun_obs/cdelt1; for (i=0;i<naxis1;i++){ for (j=0;j<naxis2;j++){ xx=(double)i-rllx; yy=(double)j-rlly; r=sqrt(xx*xx+yy*yy); if (r <= rsun_pix){ radius[j][i]=r; mu=sqrt(1-pow(r/rsun_pix,2.0)); con_dat[j][i]=con_dat[j][i]/limb_darken(mu); } } } /* Determine if we actually have an active region here. */ spotbounds(con_dat,naxis1,naxis2,&umb,&pen,umb_sig,pen_sig); num_good=0; for (i=0;i<naxis1;i++){ for (j=0;j<naxis2;j++){ if ((radius[j][i] > 0)&&(con_dat[j][i] <= pen)&&(con_dat[j][i] > 0)){ num_good++; } } } /* Now find the average LOS velocities. */ umb_p_vel[k]=0; pen_p_vel[k]=0; umb_n_vel[k]=0; pen_n_vel[k]=0; umb_p_counter=0.0; umb_n_counter=0.0; pen_p_counter=0.0; pen_n_counter=0.0; if (num_good > 0){ /* We're going to do these loops twice - first to remove any satellite and differential * rotation effects, then again to fit and remove trends. */ /* First the satellite motion and the differential rotation */ for (i=0;i<naxis1;i++){ for (j=0;j<naxis2;j++){ if ((radius[j][i] > 0)&&(good_pixel(info_dat[j][i]))){ /* Get the pixel location in HPL coordinates */ x=rpllx+(double)i; y=rplly+(double)j; /* Stonyhurst/carrington needed for photospheric velocity calcs */ pixel2hpl(x,y,crota2,imcrpix1,imcrpix2,cdelt1,cdelt2,&tx,&ty); hpl2stony(tx,ty,dsun_obs,crln_obs,crlt_obs,&lat,&lon); /* Photospheric rotation removal */ vt=v_t(lat,0,0,0)*along_phi(t,p,dsun_obs); /*0's are for default coefficients */ /* Convert to spherical with no rotation to account for sat orientation and handle LOS stuff */ pixel2hpl(x,y,0.0,imcrpix1,imcrpix2,cdelt1,cdelt2,&tx,&ty); hpl2hpc(tx,ty,&ttx,&tty); hpc2hcc(ttx,tty,dsun_obs,&xx,&yy,&zz); hcc2sphere(xx,yy,zz,&t,&p); /* LOS satellite velocity components */ vr=obs_vr*along_obs(t,p,dsun_obs); vn=obs_vn*along_north(t,p,dsun_obs); vw=obs_vw*along_west(t,p,dsun_obs); /* vlos after removing all of the doppler effects. The * division by 100 is to convert cm/s to m/s. */ vlos_dat[j][i]=(vlos_dat[j][i]/100)-vr-vn-vw-vt; } } } /* Next we fit a function across x, not including points that would be in a sunspot or off-disk points. * Then we subtract this trend from the remaining data. */ for (j=0;j<naxis2;j++){ /* Fill the arrays along x */ for (i=0;i<num_divs;i++){ if (i < (num_divs-1)){ /* There are a total of num_divs segments in a data strip. * To handle remainders when determining how many points to * place in a segment, we first do the remainderless ones. * The last may or may not have a remainder, but that's where * one would go if it did, so we do it separately. */ for (l=0;l<inv_len;l++){ n=i*inv_len+l; y_error[i][l]=1; x_axis[i][l]=(double)n; if ((radius[j][n] > 0)&&(con_dat[j][n] > pen)&&(good_pixel(info_dat[j][n]))){ y_axis[i][l]=vlos_dat[j][n]; } else { y_axis[i][l]=0.0; } } } else { /* Handle the one that might have a remainder */ for (l=0;l<(inv_len + naxis1%num_divs);l++){ n=(num_divs-1)*inv_len+l; y_error[num_divs-1][l]=1; x_axis[num_divs-1][l]=(double)n; if ((radius[j][n] > 0)&&(con_dat[j][n] > pen)&&(good_pixel(info_dat[j][n]))){ y_axis[num_divs-1][l]=vlos_dat[j][n]; } else { y_axis[num_divs-1][l]=0.0; } } } } /* Now we fit, but in strips determined by num_divs */ for (i=0;i<num_divs;i++){ if (i < (num_divs-1)){ v.x=x_axis[i]; v.y=y_axis[i]; v.ey=y_error[i]; fit_status=mpfit(fit_me,inv_len,2,fit_params,0,&config,(void *)&v,&result); for (l=0;l<inv_len;l++){ n=i*inv_len+l; vlos_dat[j][n]=vlos_dat[j][n]-(fit_params[0]*x_axis[i][l]+fit_params[1]); /* Subtract trend */ } } else { v.x=x_axis[num_divs-1]; v.y=y_axis[num_divs-1]; v.ey=y_error[num_divs-1]; fit_status=mpfit(fit_me,inv_len + naxis1%num_divs,2,fit_params,0,&config,(void *)&v,&result); for (l=0;l<(inv_len + naxis1%num_divs);l++){ n=(num_divs-1)*inv_len+l; vlos_dat[j][n]=vlos_dat[j][n]-(fit_params[0]*x_axis[num_divs-1][l]+fit_params[1]); /* Subtract trend */ } } } } /* Finally, we have a clean data set. Now get to work on it. */ for (i=0;i<naxis1;i++){ for (j=0;j<naxis2;j++){ if ((radius[j][i] > 0)&&(con_dat[j][i] < pen)&&(good_pixel(info_dat[j][i]))){ /* "Positive" sunspot polarities. */ vlos=vlos_dat[j][i]; if (inc_dat[j][i] < 90){ if (con_dat[j][i] <= umb){ umb_p_vel[k]+=vlos; umb_p_counter++; } if (con_dat[j][i] > umb){ pen_p_vel[k]+=vlos; pen_p_counter++; } } /* "Negative" sunspot polarities. */ if (inc_dat[j][i] > 90){ if (con_dat[j][i] <= umb){ umb_n_vel[k]+=vlos; umb_n_counter++; } if (con_dat[j][i] > umb){ pen_n_vel[k]+=vlos; pen_n_counter++; } } } } } } if (umb_p_counter > 0){ umb_p_vel[k]/=umb_p_counter; } else { umb_p_vel[k]=0; } if (umb_n_counter > 0){ umb_n_vel[k]/=umb_n_counter; } else { umb_n_vel[k]=0; } if (pen_p_counter > 0){ pen_p_vel[k]/=pen_p_counter; } else { pen_p_vel[k]=0; } if (pen_n_counter > 0){ pen_n_vel[k]/=pen_n_counter; } else { pen_n_vel[k]=0; } /* Free up dynamic arrays and close the files for the next iteration. */ for (i=0;i<naxis2;i++){ free(vlos_dat[i]); free(inc_dat[i]); free(con_dat[i]); free(radius[i]); free(info_dat[i]); } free(vlos_dat); free(inc_dat); free(con_dat); free(radius); free(info_dat); free(v_pixel_strip); free(i_pixel_strip); free(c_pixel_strip); free(info_pixel_strip); free(x_axis); free(y_axis); free(y_error); fits_close_file(v_ptr,&v_status); fits_close_file(i_ptr,&i_status); fits_close_file(c_ptr,&c_status); fits_close_file(info_ptr,&info_status); } } printf(" Completed run %d of %d.\n",k+1,num_records); } /* Output the results to a text file. */ /* First, convert t_obs to a more reasonable product. */ for (i=0;i<num_records;i++){ t_secs[i]=isotime(t_obs_s[i]); } printf("Writing to file %s.\n",outfile_name); outptr=fopen(outfile_name,"w"); bad_outptr=fopen(bad_outfile_name,"w"); fprintf(outptr,"Active Region: %d\tVelocities are in m/s, fvlos is scaled to remove limb effects.\n",noaa_ar); fprintf(outptr,"Full UT Time time(s) vlos pumb vlos ppen vlos numb vlos npen\n"); fprintf(outptr,"---------------------- ------- --------- --------- --------- ---------\n"); fprintf(bad_outptr,"Active Region: AR%d\n",noaa_ar); fprintf(bad_outptr,"Full UT Time quality time(s) number\n"); fprintf(bad_outptr,"---------------------- ------- ------- ------\n"); for (i=0;i<num_records;i++){ /* Make times relative to the first recorded one. */ if (quality[i] == 0){ fprintf(outptr,"%s %7ld %6.2lf %6.2lf %6.2lf %6.2lf\n",t_obs_s[i],t_secs[i]-t_secs[0],umb_p_vel[i],pen_p_vel[i],umb_n_vel[i],pen_n_vel[i]); } else { fprintf(bad_outptr,"%s 0x%08lX %7ld %d\n",t_obs_s[i],quality[i],t_secs[i],i+1); } } fclose(outptr); fclose(bad_outptr); printf("Done!\n"); /* Free memory associated with dynamic arrays. */ free(t_secs); free(t_obs_s); free(umb_p_vel); free(pen_p_vel); free(umb_n_vel); free(pen_n_vel); free(quality); /* Close the drms records connection */ drms_close_records(drms_ids,DRMS_FREE_RECORD); /* Done! */ return 0; }
int fit_peak (struct params* p, double *freq, double *amp, double *width, double*** pol, double delta_nu, double delta_k, int nnu, int ntheta, int k) { int ii, ij, ik, mpreturn; double *param, *xerror; mp_par *bounds; mp_result *mpres2; mp_config *mpconf; struct kslice sub; param = (double*) malloc(4*sizeof(double)); param[0] = *freq; param[1] = *amp; param[2] = *width; param[3] = (*amp)*0.1; mpres2 = (mp_result*) calloc(1,sizeof(mp_result)); mpconf = (mp_config*) calloc(1, sizeof(mp_config)); /* Load subsection data */ sub.par = p; sub.start = (param[0] - 1.0*param[2])/delta_nu; sub.end = (param[0] + 1.0*param[2])/delta_nu; if (sub.start < 0) sub.start = 0; if (sub.end >= nnu) sub.end = nnu-1; sub.ntheta = ntheta; sub.delta_nu = delta_nu; sub.k = (k+1)*delta_k; sub.data = malloc((sub.end-sub.start+1)*sizeof(double*)); for (ii=sub.start; ii<=sub.end; ii++) { sub.data[ii-sub.start] = malloc(ntheta*sizeof(double)); for (ik=0; ik<ntheta; ik++) { sub.data[ii-sub.start][ik] = pol[ii][k][ik]; } } bounds = malloc(4*sizeof(mp_par)); xerror = calloc(4, sizeof(double)); for (ii=0; ii<4; ii++) { bounds[ii].fixed = 0; bounds[ii].side = 0; bounds[ii].deriv_debug = 0; bounds[ii].relstep = 0.0; bounds[ii].step = 0.0; bounds[ii].limited[0] = bounds[ii].limited[1] = 0; } bounds[0].limited[0] = bounds[0].limited[1] = 1; bounds[0].limits[0] = sub.start*delta_nu; bounds[0].limits[1] = sub.end*delta_nu; bounds[1].limited[0] = 1; bounds[1].limits[0] = 0.0; bounds[2].limited[0] = bounds[2].limited[1] = 1; bounds[2].limits[0] = param[2]/2.; bounds[2].limits[1] = param[2]*2.; bounds[3].limited[0] = 1; bounds[3].limited[1] = 0; bounds[3].limits[0] = 0.0; mpconf->ftol = 1e-8; mpconf->xtol = 1e-4; mpconf->gtol = 1e-8; mpconf->covtol = 1e-10; mpconf->maxiter = 200; mpconf->nofinitecheck = 1; mpres2->xerror = xerror; mpreturn = 1; mpreturn = mpfit(&funk_single, ntheta*(sub.end-sub.start+1), 4, param, bounds, mpconf, &sub, mpres2); *freq = param[0]; *amp = param[1]+param[3];/**20.;*param[0];*/ *width = param[2]; FILE *fp; double den; fp = fopen("debug2", "w"); for (ii=sub.start; ii<=sub.end; ii++) { for (ij=0; ij<ntheta; ij++) { den = ii*delta_nu - *freq; den = den*den + (*width)*(*width)/4.0; fprintf(fp, "%f\t%f\t%f\n", ii*delta_nu, param[3]+(*amp)*(*width)/(2.0*den), sub.data[ii-sub.start][ij]); } } fclose(fp); free(param); free(bounds); free(xerror); free(mpres2); free(mpconf); for (ii=sub.start; ii<=sub.end; ii++) { free(sub.data[ii-sub.start]); } free(sub.data); return 0; }