ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/JSOC/proj/sharp/apps/sw_functions.c
(Generate patch)

Comparing proj/sharp/apps/sw_functions.c (file contents):
Revision 1.27 by xudong, Wed Mar 5 19:51:19 2014 UTC vs.
Revision 1.40 by mbobra, Mon May 24 22:17:06 2021 UTC

# Line 1 | Line 1
1 +
2   /*===========================================
3  
4 < The following 14 functions calculate the following spaceweather indices:
4 > The following functions calculate these spaceweather indices from the vector magnetic field data:
5  
6   USFLUX Total unsigned flux in Maxwells
7   MEANGAM Mean inclination angle, gamma, in degrees
# Line 17 | Line 18
18   MEANPOT Mean photospheric excess magnetic energy density in ergs per cubic centimeter
19   TOTPOT Total photospheric magnetic energy density in ergs per cubic centimeter
20   MEANSHR Mean shear angle (measured using Btotal) in degrees
21 + CMASK The total number of pixels that contributed to the calculation of all the indices listed above
22 +
23 + And these spaceweather indices from the line-of-sight magnetic field data:
24 + USFLUXL Total unsigned flux in Maxwells
25 + MEANGBL Mean value of the line-of-sight field gradient, in Gauss/Mm
26 + CMASKL The total number of pixels that contributed to the calculation of USFLUXL and MEANGBL
27 + R_VALUE Karel Schrijver's R parameter
28  
29   The indices are calculated on the pixels in which the conf_disambig segment is greater than 70 and
30   pixels in which the bitmap segment is greater than 30. These ranges are selected because the CCD
# Line 86 | Line 94 | int computeAbsFlux(float *bz_err, float
94      
95          for (i = 0; i < nx; i++)
96          {
97 <                for (j = 0; j < ny; j++)
98 <                {
97 >           for (j = 0; j < ny; j++)
98 >           {
99              if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
100              if isnan(bz[j * nx + i]) continue;
101              sum += (fabs(bz[j * nx + i]));
102              err += bz_err[j * nx + i]*bz_err[j * nx + i];
103              count_mask++;
104 <                }
104 >           }
105          }
106      
107      *mean_vf_ptr     = sum*cdelt1*cdelt1*(rsun_ref/rsun_obs)*(rsun_ref/rsun_obs)*100.0*100.0;
# Line 245 | Line 253 | int computeB_total(float *bx_err, float
253   /*===========================================*/
254   /* Example function 5:  Derivative of B_Total SQRT( (dBt/dx)^2 + (dBt/dy)^2 ) */
255  
256 < int computeBtotalderivative(float *bt, int *dims, float *mean_derivative_btotal_ptr, int *mask, int *bitmask, float *derx_bt, float *dery_bt, float *bt_err, float *mean_derivative_btotal_err_ptr)
256 > int computeBtotalderivative(float *bt, int *dims, float *mean_derivative_btotal_ptr, int *mask, int *bitmask, float *derx_bt, float *dery_bt, float *bt_err, float *mean_derivative_btotal_err_ptr, float *err_termAt, float *err_termBt)
257   {
258      
259      int nx = dims[0];
# Line 262 | Line 270 | int computeBtotalderivative(float *bt, i
270      /* brute force method of calculating the derivative (no consideration for edges) */
271      for (i = 1; i <= nx-2; i++)
272      {
273 <            for (j = 0; j <= ny-1; j++)
273 >        for (j = 0; j <= ny-1; j++)
274          {
275 <            derx_bt[j * nx + i] = (bt[j * nx + i+1] - bt[j * nx + i-1])*0.5;
275 >           derx_bt[j * nx + i] = (bt[j * nx + i+1] - bt[j * nx + i-1])*0.5;
276 >           err_termAt[j * nx + i] = (((bt[j * nx + (i+1)]-bt[j * nx + (i-1)])*(bt[j * nx + (i+1)]-bt[j * nx + (i-1)])) * (bt_err[j * nx + (i+1)]*bt_err[j * nx + (i+1)] + bt_err[j * nx + (i-1)]*bt_err[j * nx + (i-1)])) ;
277          }
278      }
279      
280      /* brute force method of calculating the derivative (no consideration for edges) */
281      for (i = 0; i <= nx-1; i++)
282      {
283 <            for (j = 1; j <= ny-2; j++)
283 >        for (j = 1; j <= ny-2; j++)
284          {
285 <            dery_bt[j * nx + i] = (bt[(j+1) * nx + i] - bt[(j-1) * nx + i])*0.5;
285 >           dery_bt[j * nx + i] = (bt[(j+1) * nx + i] - bt[(j-1) * nx + i])*0.5;
286 >           err_termBt[j * nx + i] = (((bt[(j+1) * nx + i]-bt[(j-1) * nx + i])*(bt[(j+1) * nx + i]-bt[(j-1) * nx + i])) * (bt_err[(j+1) * nx + i]*bt_err[(j+1) * nx + i] + bt_err[(j-1) * nx + i]*bt_err[(j-1) * nx + i])) ;
287          }
288      }
289      
290 <    
291 <    /* consider the edges */
290 >    /* consider the edges for the arrays that contribute to the variable "sum" in the computation below.
291 >    ignore the edges for the error terms as those arrays have been initialized to zero.
292 >    this is okay because the error term will ultimately not include the edge pixels as they are selected out by the mask and bitmask arrays.*/
293      i=0;
294      for (j = 0; j <= ny-1; j++)
295      {
# Line 302 | Line 313 | int computeBtotalderivative(float *bt, i
313      {
314          dery_bt[j * nx + i] = ( (3*bt[j * nx + i]) + (-4*bt[(j-1) * nx + i]) - (-bt[(j-2) * nx + i]) )*0.5;
315      }
316 <    
317 <    
316 >
317 >    // Calculate the sum only
318      for (i = 1; i <= nx-2; i++)
319      {
320          for (j = 1; j <= ny-2; j++)
# Line 319 | Line 330 | int computeBtotalderivative(float *bt, i
330              if isnan(derx_bt[j * nx + i]) continue;
331              if isnan(dery_bt[j * nx + i]) continue;
332              sum += sqrt( derx_bt[j * nx + i]*derx_bt[j * nx + i]  + dery_bt[j * nx + i]*dery_bt[j * nx + i]  ); /* Units of Gauss */
333 <            err += (((bt[(j+1) * nx + i]-bt[(j-1) * nx + i])*(bt[(j+1) * nx + i]-bt[(j-1) * nx + i])) * (bt_err[(j+1) * nx + i]*bt_err[(j+1) * nx + i] + bt_err[(j-1) * nx + i]*bt_err[(j-1) * nx + i])) / (16.0*( derx_bt[j * nx + i]*derx_bt[j * nx + i]  + dery_bt[j * nx + i]*dery_bt[j * nx + i]  ))+
334 <            (((bt[j * nx + (i+1)]-bt[j * nx + (i-1)])*(bt[j * nx + (i+1)]-bt[j * nx + (i-1)])) * (bt_err[j * nx + (i+1)]*bt_err[j * nx + (i+1)] + bt_err[j * nx + (i-1)]*bt_err[j * nx + (i-1)])) / (16.0*( derx_bt[j * nx + i]*derx_bt[j * nx + i]  + dery_bt[j * nx + i]*dery_bt[j * nx + i]  )) ;
333 >            err += err_termBt[j * nx + i] / (16.0*( derx_bt[j * nx + i]*derx_bt[j * nx + i]  + dery_bt[j * nx + i]*dery_bt[j * nx + i]  ))+
334 >                   err_termAt[j * nx + i] / (16.0*( derx_bt[j * nx + i]*derx_bt[j * nx + i]  + dery_bt[j * nx + i]*dery_bt[j * nx + i]  )) ;
335              count_mask++;
336          }
337      }
# Line 337 | Line 348 | int computeBtotalderivative(float *bt, i
348   /*===========================================*/
349   /* Example function 6:  Derivative of Bh SQRT( (dBh/dx)^2 + (dBh/dy)^2 ) */
350  
351 < int computeBhderivative(float *bh, float *bh_err, int *dims, float *mean_derivative_bh_ptr, float *mean_derivative_bh_err_ptr, int *mask, int *bitmask, float *derx_bh, float *dery_bh)
351 > int computeBhderivative(float *bh, float *bh_err, int *dims, float *mean_derivative_bh_ptr, float *mean_derivative_bh_err_ptr, int *mask, int *bitmask, float *derx_bh, float *dery_bh, float *err_termAh, float *err_termBh)
352   {
353      
354      int nx = dims[0];
# Line 354 | Line 365 | int computeBhderivative(float *bh, float
365      /* brute force method of calculating the derivative (no consideration for edges) */
366      for (i = 1; i <= nx-2; i++)
367      {
368 <            for (j = 0; j <= ny-1; j++)
368 >        for (j = 0; j <= ny-1; j++)
369          {
370 <            derx_bh[j * nx + i] = (bh[j * nx + i+1] - bh[j * nx + i-1])*0.5;
370 >           derx_bh[j * nx + i] = (bh[j * nx + i+1] - bh[j * nx + i-1])*0.5;
371 >           err_termAh[j * nx + i] = (((bh[j * nx + (i+1)]-bh[j * nx + (i-1)])*(bh[j * nx + (i+1)]-bh[j * nx + (i-1)])) * (bh_err[j * nx + (i+1)]*bh_err[j * nx + (i+1)] + bh_err[j * nx + (i-1)]*bh_err[j * nx + (i-1)]));
372          }
373      }
374      
375      /* brute force method of calculating the derivative (no consideration for edges) */
376      for (i = 0; i <= nx-1; i++)
377      {
378 <            for (j = 1; j <= ny-2; j++)
379 <        {
380 <            dery_bh[j * nx + i] = (bh[(j+1) * nx + i] - bh[(j-1) * nx + i])*0.5;
381 <        }
378 >       for (j = 1; j <= ny-2; j++)
379 >       {
380 >          dery_bh[j * nx + i] = (bh[(j+1) * nx + i] - bh[(j-1) * nx + i])*0.5;
381 >          err_termBh[j * nx + i] = (((bh[ (j+1) * nx + i]-bh[(j-1) * nx + i])*(bh[(j+1) * nx + i]-bh[(j-1) * nx + i])) * (bh_err[(j+1) * nx + i]*bh_err[(j+1) * nx + i] + bh_err[(j-1) * nx + i]*bh_err[(j-1) * nx + i]));
382 >       }
383      }
384      
385 <    
386 <    /* consider the edges */
385 >    /* consider the edges for the arrays that contribute to the variable "sum" in the computation below.
386 >    ignore the edges for the error terms as those arrays have been initialized to zero.
387 >    this is okay because the error term will ultimately not include the edge pixels as they are selected out by the mask and bitmask arrays.*/
388      i=0;
389      for (j = 0; j <= ny-1; j++)
390      {
# Line 411 | Line 425 | int computeBhderivative(float *bh, float
425              if isnan(derx_bh[j * nx + i]) continue;
426              if isnan(dery_bh[j * nx + i]) continue;
427              sum += sqrt( derx_bh[j * nx + i]*derx_bh[j * nx + i]  + dery_bh[j * nx + i]*dery_bh[j * nx + i]  ); /* Units of Gauss */
428 <            err += (((bh[(j+1) * nx + i]-bh[(j-1) * nx + i])*(bh[(j+1) * nx + i]-bh[(j-1) * nx + i])) * (bh_err[(j+1) * nx + i]*bh_err[(j+1) * nx + i] + bh_err[(j-1) * nx + i]*bh_err[(j-1) * nx + i])) / (16.0*( derx_bh[j * nx + i]*derx_bh[j * nx + i]  + dery_bh[j * nx + i]*dery_bh[j * nx + i]  ))+
429 <            (((bh[j * nx + (i+1)]-bh[j * nx + (i-1)])*(bh[j * nx + (i+1)]-bh[j * nx + (i-1)])) * (bh_err[j * nx + (i+1)]*bh_err[j * nx + (i+1)] + bh_err[j * nx + (i-1)]*bh_err[j * nx + (i-1)])) / (16.0*( derx_bh[j * nx + i]*derx_bh[j * nx + i]  + dery_bh[j * nx + i]*dery_bh[j * nx + i]  )) ;
428 >            err += err_termBh[j * nx + i] / (16.0*( derx_bh[j * nx + i]*derx_bh[j * nx + i]  + dery_bh[j * nx + i]*dery_bh[j * nx + i]  ))+
429 >                   err_termAh[j * nx + i] / (16.0*( derx_bh[j * nx + i]*derx_bh[j * nx + i]  + dery_bh[j * nx + i]*dery_bh[j * nx + i]  )) ;
430              count_mask++;
431          }
432      }
# Line 428 | Line 442 | int computeBhderivative(float *bh, float
442   /*===========================================*/
443   /* Example function 7:  Derivative of B_vertical SQRT( (dBz/dx)^2 + (dBz/dy)^2 ) */
444  
445 < int computeBzderivative(float *bz, float *bz_err, int *dims, float *mean_derivative_bz_ptr, float *mean_derivative_bz_err_ptr, int *mask, int *bitmask, float *derx_bz, float *dery_bz)
445 > int computeBzderivative(float *bz, float *bz_err, int *dims, float *mean_derivative_bz_ptr, float *mean_derivative_bz_err_ptr, int *mask, int *bitmask, float *derx_bz, float *dery_bz, float *err_termA, float *err_termB)
446   {
447      
448      int nx = dims[0];
# Line 436 | Line 450 | int computeBzderivative(float *bz, float
450      int i = 0;
451      int j = 0;
452      int count_mask = 0;
453 <        double sum = 0.0;
453 >    double sum = 0.0;
454      double err = 0.0;
455 <        *mean_derivative_bz_ptr = 0.0;
455 >    *mean_derivative_bz_ptr = 0.0;
456      
457 <        if (nx <= 0 || ny <= 0) return 1;
457 >    if (nx <= 0 || ny <= 0) return 1;
458      
459      /* brute force method of calculating the derivative (no consideration for edges) */
460      for (i = 1; i <= nx-2; i++)
461      {
462 <            for (j = 0; j <= ny-1; j++)
462 >        for (j = 0; j <= ny-1; j++)
463          {
464 <            if isnan(bz[j * nx + i]) continue;
465 <            derx_bz[j * nx + i] = (bz[j * nx + i+1] - bz[j * nx + i-1])*0.5;
464 >           derx_bz[j * nx + i] = (bz[j * nx + i+1] - bz[j * nx + i-1])*0.5;
465 >           err_termA[j * nx + i] = (((bz[j * nx + (i+1)]-bz[j * nx + (i-1)])*(bz[j * nx + (i+1)]-bz[j * nx + (i-1)])) * (bz_err[j * nx + (i+1)]*bz_err[j * nx + (i+1)] + bz_err[j * nx + (i-1)]*bz_err[j * nx + (i-1)]));
466          }
467      }
468      
469      /* brute force method of calculating the derivative (no consideration for edges) */
470      for (i = 0; i <= nx-1; i++)
471      {
472 <            for (j = 1; j <= ny-2; j++)
472 >        for (j = 1; j <= ny-2; j++)
473          {
474 <            if isnan(bz[j * nx + i]) continue;
475 <            dery_bz[j * nx + i] = (bz[(j+1) * nx + i] - bz[(j-1) * nx + i])*0.5;
474 >           dery_bz[j * nx + i] = (bz[(j+1) * nx + i] - bz[(j-1) * nx + i])*0.5;
475 >           err_termB[j * nx + i] = (((bz[(j+1) * nx + i]-bz[(j-1) * nx + i])*(bz[(j+1) * nx + i]-bz[(j-1) * nx + i])) * (bz_err[(j+1) * nx + i]*bz_err[(j+1) * nx + i] + bz_err[(j-1) * nx + i]*bz_err[(j-1) * nx + i]));
476          }
477      }
478      
479 <    
480 <    /* consider the edges */
479 >    /* consider the edges for the arrays that contribute to the variable "sum" in the computation below.
480 >    ignore the edges for the error terms as those arrays have been initialized to zero.
481 >    this is okay because the error term will ultimately not include the edge pixels as they are selected out by the mask and bitmask arrays.*/
482      i=0;
483      for (j = 0; j <= ny-1; j++)
484      {
470        if isnan(bz[j * nx + i]) continue;
485          derx_bz[j * nx + i] = ( (-3*bz[j * nx + i]) + (4*bz[j * nx + (i+1)]) - (bz[j * nx + (i+2)]) )*0.5;
486      }
487      
488      i=nx-1;
489      for (j = 0; j <= ny-1; j++)
490      {
477        if isnan(bz[j * nx + i]) continue;
491          derx_bz[j * nx + i] = ( (3*bz[j * nx + i]) + (-4*bz[j * nx + (i-1)]) - (-bz[j * nx + (i-2)]) )*0.5;
492      }
493      
494      j=0;
495      for (i = 0; i <= nx-1; i++)
496      {
484        if isnan(bz[j * nx + i]) continue;
497          dery_bz[j * nx + i] = ( (-3*bz[j*nx + i]) + (4*bz[(j+1) * nx + i]) - (bz[(j+2) * nx + i]) )*0.5;
498      }
499      
500      j=ny-1;
501      for (i = 0; i <= nx-1; i++)
502      {
491        if isnan(bz[j * nx + i]) continue;
503          dery_bz[j * nx + i] = ( (3*bz[j * nx + i]) + (-4*bz[(j-1) * nx + i]) - (-bz[(j-2) * nx + i]) )*0.5;
504      }
505      
# Line 507 | Line 518 | int computeBzderivative(float *bz, float
518              if isnan(bz_err[j * nx + i])  continue;
519              if isnan(derx_bz[j * nx + i]) continue;
520              if isnan(dery_bz[j * nx + i]) continue;
521 <            sum += sqrt( derx_bz[j * nx + i]*derx_bz[j * nx + i]  + dery_bz[j * nx + i]*dery_bz[j * nx + i]  ); /* Units of Gauss */
522 <            err += (((bz[(j+1) * nx + i]-bz[(j-1) * nx + i])*(bz[(j+1) * nx + i]-bz[(j-1) * nx + i])) * (bz_err[(j+1) * nx + i]*bz_err[(j+1) * nx + i] + bz_err[(j-1) * nx + i]*bz_err[(j-1) * nx + i])) /
523 <            (16.0*( derx_bz[j * nx + i]*derx_bz[j * nx + i]  + dery_bz[j * nx + i]*dery_bz[j * nx + i]  )) +
513 <            (((bz[j * nx + (i+1)]-bz[j * nx + (i-1)])*(bz[j * nx + (i+1)]-bz[j * nx + (i-1)])) * (bz_err[j * nx + (i+1)]*bz_err[j * nx + (i+1)] + bz_err[j * nx + (i-1)]*bz_err[j * nx + (i-1)])) /
514 <            (16.0*( derx_bz[j * nx + i]*derx_bz[j * nx + i]  + dery_bz[j * nx + i]*dery_bz[j * nx + i]  )) ;
521 >            sum += sqrt( derx_bz[j * nx + i]*derx_bz[j * nx + i]  + dery_bz[j * nx + i]*dery_bz[j * nx + i] ); /* Units of Gauss */
522 >            err += err_termB[j * nx + i] / (16.0*( derx_bz[j * nx + i]*derx_bz[j * nx + i]  + dery_bz[j * nx + i]*dery_bz[j * nx + i]  )) +
523 >                   err_termA[j * nx + i] / (16.0*( derx_bz[j * nx + i]*derx_bz[j * nx + i]  + dery_bz[j * nx + i]*dery_bz[j * nx + i]  )) ;
524              count_mask++;
525          }
526      }
527      
528 <        *mean_derivative_bz_ptr = (sum)/(count_mask); // would be divided by ((nx-2)*(ny-2)) if shape of count_mask = shape of magnetogram
528 >    *mean_derivative_bz_ptr = (sum)/(count_mask); // would be divided by ((nx-2)*(ny-2)) if shape of count_mask = shape of magnetogram
529      *mean_derivative_bz_err_ptr = (sqrt(err))/(count_mask); // error in the quantity (sum)/(count_mask)
530      //printf("MEANGBZ=%f\n",*mean_derivative_bz_ptr);
531      //printf("MEANGBZ_err=%f\n",*mean_derivative_bz_err_ptr);
# Line 557 | Line 566 | int computeBzderivative(float *bz, float
566  
567  
568   // Comment out random number generator, which can only run on solar3
569 < //int computeJz(float *bx_err, float *by_err, float *bx, float *by, int *dims, float *jz, float *jz_err, float *jz_err_squared,
569 > // int computeJz(float *bx_err, float *by_err, float *bx, float *by, int *dims, float *jz, float *jz_err, float *jz_err_squared,
570   //            int *mask, int *bitmask, float cdelt1, double rsun_ref, double rsun_obs,float *derx, float *dery, float *noisebx,
571   //              float *noiseby, float *noisebz)
572  
573   int computeJz(float *bx_err, float *by_err, float *bx, float *by, int *dims, float *jz, float *jz_err, float *jz_err_squared,
574 <              int *mask, int *bitmask, float cdelt1, double rsun_ref, double rsun_obs,float *derx, float *dery)
574 >              int *mask, int *bitmask, float cdelt1, double rsun_ref, double rsun_obs,float *derx, float *dery, float *err_term1, float *err_term2)
575  
576  
577   {
# Line 579 | Line 588 | int computeJz(float *bx_err, float *by_e
588      
589      for (i = 1; i <= nx-2; i++)
590      {
591 <            for (j = 0; j <= ny-1; j++)
591 >        for (j = 0; j <= ny-1; j++)
592          {
593 <            if isnan(by[j * nx + i]) continue;
594 <            derx[j * nx + i] = (by[j * nx + i+1] - by[j * nx + i-1])*0.5;
593 >           derx[j * nx + i]      = (by[j * nx + i+1] - by[j * nx + i-1])*0.5;
594 >           err_term1[j * nx + i] = (by_err[j * nx + i+1])*(by_err[j * nx + i+1]) + (by_err[j * nx + i-1])*(by_err[j * nx + i-1]);
595          }
596      }
597      
598      for (i = 0; i <= nx-1; i++)
599      {
600 <            for (j = 1; j <= ny-2; j++)
600 >        for (j = 1; j <= ny-2; j++)
601          {
602 <            if isnan(bx[j * nx + i]) continue;
603 <            dery[j * nx + i] = (bx[(j+1) * nx + i] - bx[(j-1) * nx + i])*0.5;
602 >           dery[j * nx + i]      = (bx[(j+1) * nx + i] - bx[(j-1) * nx + i])*0.5;
603 >           err_term2[j * nx + i] = (bx_err[(j+1) * nx + i])*(bx_err[(j+1) * nx + i]) + (bx_err[(j-1) * nx + i])*(bx_err[(j-1) * nx + i]);
604          }
605      }
606 <    
607 <    // consider the edges
606 >
607 >    /* consider the edges for the arrays that contribute to the variable "sum" in the computation below.
608 >    ignore the edges for the error terms as those arrays have been initialized to zero.
609 >    this is okay because the error term will ultimately not include the edge pixels as they are selected out by the mask and bitmask arrays.*/
610 >
611      i=0;
612      for (j = 0; j <= ny-1; j++)
613      {
614 <        if isnan(by[j * nx + i]) continue;
603 <        derx[j * nx + i] = ( (-3*by[j * nx + i]) + (4*by[j * nx + (i+1)]) - (by[j * nx + (i+2)]) )*0.5;
614 >        derx[j * nx + i]      = ( (-3*by[j * nx + i]) + (4*by[j * nx + (i+1)]) - (by[j * nx + (i+2)]) )*0.5;
615      }
616      
617      i=nx-1;
618      for (j = 0; j <= ny-1; j++)
619      {
620 <        if isnan(by[j * nx + i]) continue;
610 <        derx[j * nx + i] = ( (3*by[j * nx + i]) + (-4*by[j * nx + (i-1)]) - (-by[j * nx + (i-2)]) )*0.5;
620 >        derx[j * nx + i]      = ( (3*by[j * nx + i]) + (-4*by[j * nx + (i-1)]) - (-by[j * nx + (i-2)]) )*0.5;
621      }
622      
623      j=0;
624      for (i = 0; i <= nx-1; i++)
625      {
626 <        if isnan(bx[j * nx + i]) continue;
617 <        dery[j * nx + i] = ( (-3*bx[j*nx + i]) + (4*bx[(j+1) * nx + i]) - (bx[(j+2) * nx + i]) )*0.5;
626 >        dery[j * nx + i]      = ( (-3*bx[j*nx + i]) + (4*bx[(j+1) * nx + i]) - (bx[(j+2) * nx + i]) )*0.5;
627      }
628      
629      j=ny-1;
630      for (i = 0; i <= nx-1; i++)
631      {
632 <        if isnan(bx[j * nx + i]) continue;
624 <        dery[j * nx + i] = ( (3*bx[j * nx + i]) + (-4*bx[(j-1) * nx + i]) - (-bx[(j-2) * nx + i]) )*0.5;
632 >        dery[j * nx + i]      = ( (3*bx[j * nx + i]) + (-4*bx[(j-1) * nx + i]) - (-bx[(j-2) * nx + i]) )*0.5;
633      }
634 +
635      
636 <    for (i = 1; i <= nx-2; i++)
636 >    for (i = 0; i <= nx-1; i++)
637      {
638 <        for (j = 1; j <= ny-2; j++)
638 >        for (j = 0; j <= ny-1; j++)
639          {
640 <            // calculate jz at all points
632 <            
640 >            // calculate jz at all points        
641              jz[j * nx + i]            = (derx[j * nx + i]-dery[j * nx + i]);       // jz is in units of Gauss/pix
642 <            jz_err[j * nx + i]        = 0.5*sqrt( (bx_err[(j+1) * nx + i]*bx_err[(j+1) * nx + i]) + (bx_err[(j-1) * nx + i]*bx_err[(j-1) * nx + i]) +
635 <                                                 (by_err[j * nx + (i+1)]*by_err[j * nx + (i+1)]) + (by_err[j * nx + (i-1)]*by_err[j * nx + (i-1)]) ) ;
642 >            jz_err[j * nx + i]        = 0.5*sqrt( err_term1[j * nx + i] + err_term2[j * nx + i] ) ;
643              jz_err_squared[j * nx + i]= (jz_err[j * nx + i]*jz_err[j * nx + i]);
644 <            count_mask++;
638 <            
644 >            count_mask++;            
645          }
646      }
647          return 0;
648   }
649 <
649 >
650   /*===========================================*/
651  
652   /* Example function 9:  Compute quantities on Jz array */
# Line 831 | Line 837 | int computeHelicity(float *jz_err, float
837   /* Example function 12:  Sum of Absolute Value per polarity  */
838  
839   //  The Sum of the Absolute Value per polarity is defined as the following:
840 < //  fabs(sum(jz gt 0)) + fabs(sum(jz lt 0)) and the units are in Amperes.
840 > //  fabs(sum(jz gt 0)) + fabs(sum(jz lt 0)) and the units are in Amperes per square arcsecond.
841   //  The units of jz are in G/pix. In this case, we would have the following:
842   //  Jz = (Gauss/pix)(1/CDELT1)(0.00010)(1/MUNAUGHT)(RSUN_REF/RSUN_OBS)(RSUN_REF/RSUN_OBS)(RSUN_OBS/RSUN_REF),
843   //     = (Gauss/pix)(1/CDELT1)(0.00010)(1/MUNAUGHT)(RSUN_REF/RSUN_OBS)
# Line 847 | Line 853 | int computeSumAbsPerPolarity(float *jz_e
853      int i=0;
854      int j=0;
855      int count_mask=0;
856 <        double sum1=0.0;
856 >    double sum1=0.0;
857      double sum2=0.0;
858      double err=0.0;
859 <        *totaljzptr=0.0;
859 >    *totaljzptr=0.0;
860      
861 <        if (nx <= 0 || ny <= 0) return 1;
861 >    if (nx <= 0 || ny <= 0) return 1;
862      
863 <        for (i = 0; i < nx; i++)
863 >    for (i = 0; i < nx; i++)
864      {
865 <            for (j = 0; j < ny; j++)
865 >         for (j = 0; j < ny; j++)
866          {
867              if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
868              if isnan(bz[j * nx + i]) continue;
# Line 868 | Line 874 | int computeSumAbsPerPolarity(float *jz_e
874          }
875      }
876          
877 <        *totaljzptr    = fabs(sum1) + fabs(sum2);  /* Units are A */
877 >    *totaljzptr    = fabs(sum1) + fabs(sum2);  /* Units are Amperes per arcsecond */
878      *totaljz_err_ptr = sqrt(err)*(1/cdelt1)*fabs((0.00010)*(1/MUNAUGHT)*(rsun_ref/rsun_obs));
879      //printf("SAVNCPP=%g\n",*totaljzptr);
880      //printf("SAVNCPP_err=%g\n",*totaljz_err_ptr);
881      
882 <        return 0;
882 >    return 0;
883   }
884  
885   /*===========================================*/
# Line 899 | Line 905 | int computeFreeEnergy(float *bx_err, flo
905      int i = 0;
906      int j = 0;
907      int count_mask = 0;
908 <        double sum = 0.0;
908 >    double sum = 0.0;
909      double sum1 = 0.0;
910      double err = 0.0;
911      *totpotptr = 0.0;
912 <        *meanpotptr = 0.0;
912 >    *meanpotptr = 0.0;
913      
914 <        if (nx <= 0 || ny <= 0) return 1;
914 >    if (nx <= 0 || ny <= 0) return 1;
915      
916 <        for (i = 0; i < nx; i++)
916 >    for (i = 0; i < nx; i++)
917      {
918 <            for (j = 0; j < ny; j++)
918 >        for (j = 0; j < ny; j++)
919          {
920              if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
921              if isnan(bx[j * nx + i]) continue;
# Line 936 | Line 942 | int computeFreeEnergy(float *bx_err, flo
942      //printf("TOTPOT=%g\n",*totpotptr);
943      //printf("TOTPOT_err=%g\n",*totpot_err_ptr);
944      
945 <        return 0;
945 >    return 0;
946   }
947  
948   /*===========================================*/
# Line 967 | Line 973 | int computeShearAngle(float *bx_err, flo
973      double part2 = 0.0;
974      double part3 = 0.0;
975      *area_w_shear_gt_45ptr = 0.0;
976 <        *meanshear_angleptr = 0.0;
976 >    *meanshear_angleptr = 0.0;
977          
978 <        if (nx <= 0 || ny <= 0) return 1;
978 >    if (nx <= 0 || ny <= 0) return 1;
979      
980 <        for (i = 0; i < nx; i++)
980 >    for (i = 0; i < nx; i++)
981      {
982 <            for (j = 0; j < ny; j++)
982 >        for (j = 0; j < ny; j++)
983          {
984              if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
985              if isnan(bpx[j * nx + i]) continue;
# Line 1022 | Line 1028 | int computeShearAngle(float *bx_err, flo
1028      }
1029      /* For mean 3D shear angle, area with shear greater than 45*/
1030      *meanshear_angleptr = (sumsum)/(count);                 /* Units are degrees */
1031 <    *meanshear_angle_err_ptr = (sqrt(err)/count_mask)*(180./PI);
1031 >    
1032 >    // For the error in the mean 3D shear angle:
1033 >    // If count_mask is 0, then we run into a divide by zero error. In this case, set *meanshear_angle_err_ptr to NAN
1034 >    // If count_mask is greater than zero, then compute the error.
1035 >    if (count_mask == 0)
1036 >        *meanshear_angle_err_ptr = NAN;
1037 >    else
1038 >        *meanshear_angle_err_ptr = (sqrt(err)/count_mask)*(180./PI);
1039      
1040      /* The area here is a fractional area -- the % of the total area. This has no error associated with it. */
1041      *area_w_shear_gt_45ptr   = (count_mask/(count))*(100.0);
1042      
1043      //printf("MEANSHR=%f\n",*meanshear_angleptr);
1044 <    //printf("MEANSHR_err=%f\n",*meanshear_angle_err_ptr);
1044 >    //printf("ERRMSHA=%f\n",*meanshear_angle_err_ptr);
1045      //printf("SHRGT45=%f\n",*area_w_shear_gt_45ptr);
1046 <    
1034 <        return 0;
1046 >    return 0;
1047   }
1048  
1049   /*===========================================*/
1050 + /* Example function 15: R parameter as defined in Schrijver, 2007 */
1051 + //
1052 + // Note that there is a restriction on the function fsample()
1053 + // If the following occurs:
1054 + //      nx_out > floor((ny_in-1)/scale + 1)
1055 + //      ny_out > floor((ny_in-1)/scale + 1),
1056 + // where n*_out are the dimensions of the output array and n*_in
1057 + // are the dimensions of the input array, fsample() will usually result
1058 + // in a segfault (though not always, depending on how the segfault was accessed.)
1059 +
1060   int computeR(float *bz_err, float *los, int *dims, float *Rparam, float cdelt1,
1061               float *rim, float *p1p0, float *p1n0, float *p1p, float *p1n, float *p1,
1062 <             float *pmap, int nx1, int ny1)
1063 < {
1064 <    
1062 >             float *pmap, int nx1, int ny1,
1063 >             int scale, float *p1pad, int nxp, int nyp, float *pmapn)
1064 >
1065 > {
1066      int nx = dims[0];
1067      int ny = dims[1];
1068      int i = 0;
1069      int j = 0;
1070 <    int index;
1070 >    int index, index1;
1071      double sum = 0.0;
1072      double err = 0.0;
1073      *Rparam = 0.0;
1074      struct fresize_struct fresboxcar, fresgauss;
1075 <    int scale = round(2.0/cdelt1);
1075 >    struct fint_struct fints;
1076      float sigma = 10.0/2.3548;
1077      
1078 +    // set up convolution kernels
1079      init_fresize_boxcar(&fresboxcar,1,1);
1056    
1057    // set up convolution kernel
1080      init_fresize_gaussian(&fresgauss,sigma,20,1);
1081 <    
1082 <    // make sure convolution kernel is smaller than or equal to array size
1083 <    if ( (nx  < 41.) || (ny < 41.) ) return -1;
1062 <    
1081 >
1082 >    // =============== [STEP 1] ===============
1083 >    // bin the line-of-sight magnetogram down by a factor of scale
1084      fsample(los, rim, nx, ny, nx, nx1, ny1, nx1, scale, 0, 0, 0.0);
1085 +
1086 +    // =============== [STEP 2] ===============
1087 +    // identify positive and negative pixels greater than +/- 150 gauss
1088 +    // and label those pixels with a 1.0 in arrays p1p0 and p1n0
1089      for (i = 0; i < nx1; i++)
1090      {
1091          for (j = 0; j < ny1; j++)
# Line 1076 | Line 1101 | int computeR(float *bz_err, float *los,
1101                  p1n0[index]=0.0;
1102          }
1103      }
1104 <    
1104 >
1105 >    // =============== [STEP 3] ===============
1106 >    // smooth each of the negative and positive pixel bitmaps      
1107      fresize(&fresboxcar, p1p0, p1p, nx1, ny1, nx1, nx1, ny1, nx1, 0, 0, 0.0);
1108      fresize(&fresboxcar, p1n0, p1n, nx1, ny1, nx1, nx1, ny1, nx1, 0, 0, 0.0);
1109 <    
1109 >
1110 >    // =============== [STEP 4] ===============
1111 >    // find the pixels for which p1p and p1n are both equal to 1.
1112 >    // this defines the polarity inversion line
1113      for (i = 0; i < nx1; i++)
1114      {
1115          for (j = 0; j < ny1; j++)
1116          {
1117              index = j * nx1 + i;
1118 <            if (p1p[index] > 0 && p1n[index] > 0)
1118 >            if ((p1p[index] > 0.0) && (p1n[index] > 0.0))
1119                  p1[index]=1.0;
1120              else
1121                  p1[index]=0.0;
1122          }
1123      }
1124 <    
1125 <    fresize(&fresgauss, p1, pmap, nx1, ny1, nx1, nx1, ny1, nx1, 0, 0, 0.0);
1126 <    
1124 >
1125 >    // pad p1 with zeroes so that the gaussian colvolution in step 5
1126 >    // does not cut off data within hwidth of the edge
1127 >  
1128 >    // step i: zero p1pad
1129 >    for (i = 0; i < nxp; i++)
1130 >    {
1131 >        for (j = 0; j < nyp; j++)
1132 >        {
1133 >            index = j * nxp + i;
1134 >            p1pad[index]=0.0;
1135 >        }
1136 >    }
1137 >
1138 >    // step ii: place p1 at the center of p1pad
1139 >    for (i = 0; i < nx1; i++)
1140 >    {
1141 >       for (j = 0; j < ny1; j++)
1142 >       {
1143 >            index  = j * nx1 + i;
1144 >            index1 = (j+20) * nxp + (i+20);
1145 >            p1pad[index1]=p1[index];
1146 >        }
1147 >    }
1148 >
1149 >    // =============== [STEP 5] ===============
1150 >    // convolve the polarity inversion line map with a gaussian
1151 >    // to identify the region near the plarity inversion line
1152 >    // the resultant array is called pmap
1153 >    fresize(&fresgauss, p1pad, pmap, nxp, nyp, nxp, nxp, nyp, nxp, 0, 0, 0.0);
1154 >
1155 >
1156 >   // select out the nx1 x ny1 non-padded array  within pmap
1157 >    for (i = 0; i < nx1; i++)
1158 >    {
1159 >       for (j = 0; j < ny1; j++)
1160 >       {
1161 >            index  = j * nx1 + i;
1162 >            index1 = (j+20) * nxp + (i+20);
1163 >            pmapn[index]=pmap[index1];
1164 >        }
1165 >    }
1166 >
1167 >    // =============== [STEP 6] ===============
1168 >    // the R parameter is calculated
1169      for (i = 0; i < nx1; i++)
1170      {
1171          for (j = 0; j < ny1; j++)
1172          {
1173              index = j * nx1 + i;
1174 <            sum += pmap[index]*abs(rim[index]);
1174 >            if isnan(pmapn[index]) continue;
1175 >            if isnan(rim[index]) continue;
1176 >            sum += pmapn[index]*abs(rim[index]);
1177          }
1178      }
1179      
# Line 1107 | Line 1181 | int computeR(float *bz_err, float *los,
1181          *Rparam = 0.0;
1182      else
1183          *Rparam = log10(sum);
1184 <    
1184 >
1185 >    //printf("R_VALUE=%f\n",*Rparam);
1186 >
1187      free_fresize(&fresboxcar);
1188      free_fresize(&fresgauss);
1189 +
1190 +    return 0;
1191 +
1192 + }
1193 +
1194 + /*===========================================*/
1195 + /* Example function 16: Lorentz force as defined in Fisher, 2012 */
1196 + //
1197 + // This calculation is adapted from Xudong's code
1198 + // at /proj/cgem/lorentz/apps/lorentz.c
1199 +
1200 + int computeLorentz(float *bx,  float *by, float *bz, float *fx, float *fy, float *fz, int *dims,
1201 +                   float *totfx_ptr, float *totfy_ptr, float *totfz_ptr, float *totbsq_ptr,
1202 +                   float *epsx_ptr, float *epsy_ptr, float *epsz_ptr, int *mask, int *bitmask,
1203 +                   float cdelt1, double rsun_ref, double rsun_obs)
1204 +
1205 + {
1206 +
1207 +    int nx = dims[0];
1208 +    int ny = dims[1];
1209 +    int nxny = nx*ny;
1210 +    int j = 0;
1211 +    int index;
1212 +    double totfx = 0, totfy = 0, totfz = 0;
1213 +    double bsq = 0, totbsq = 0;
1214 +    double epsx = 0, epsy = 0, epsz = 0;
1215 +    double area = cdelt1*cdelt1*(rsun_ref/rsun_obs)*(rsun_ref/rsun_obs)*100.0*100.0;
1216 +    double k_h = -1.0 * area / (4. * PI) / 1.0e20;
1217 +    double k_z = area / (8. * PI) / 1.0e20;
1218 +
1219 +    if (nx <= 0 || ny <= 0) return 1;        
1220 +
1221 +    for (int i = 0; i < nxny; i++)
1222 +    {  
1223 +       if ( mask[i] < 70 || bitmask[i] < 30 ) continue;
1224 +       if isnan(bx[i]) continue;
1225 +       if isnan(by[i]) continue;
1226 +       if isnan(bz[i]) continue;
1227 +       fx[i]  = bx[i] * bz[i] * k_h;
1228 +       fy[i]  = by[i] * bz[i] * k_h;
1229 +       fz[i]  = (bx[i] * bx[i] + by[i] * by[i] - bz[i] * bz[i]) * k_z;
1230 +       bsq    = bx[i] * bx[i] + by[i] * by[i] + bz[i] * bz[i];
1231 +       totfx  += fx[i]; totfy += fy[i]; totfz += fz[i];
1232 +       totbsq += bsq;
1233 +    }
1234 +  
1235 +    *totfx_ptr  = totfx;
1236 +    *totfy_ptr  = totfy;
1237 +    *totfz_ptr  = totfz;    
1238 +    *totbsq_ptr = totbsq;  
1239 +    *epsx_ptr   = (totfx / k_h) / totbsq;
1240 +    *epsy_ptr   = (totfy / k_h) / totbsq;
1241 +    *epsz_ptr   = (totfz / k_z) / totbsq;
1242 +
1243 +    //printf("TOTBSQ=%f\n",*totbsq_ptr);
1244 +
1245 +    return 0;
1246 +
1247 + }
1248 +
1249 + /*===========================================*/
1250 +
1251 + /* Example function 17: Compute total unsigned flux in units of G/cm^2 on the LOS field */
1252 +
1253 + //  To compute the unsigned flux, we simply calculate
1254 + //  flux = surface integral [(vector LOS) dot (normal vector)],
1255 + //       = surface integral [(magnitude LOS)*(magnitude normal)*(cos theta)].
1256 + //  However, since the field is radial, we will assume cos theta = 1.
1257 + //  Therefore the pixels only need to be corrected for the projection.
1258 +
1259 + //  To convert G to G*cm^2, simply multiply by the number of square centimeters per pixel.
1260 + //  As an order of magnitude estimate, we can assign 0.5 to CDELT1 and 722500m/arcsec to (RSUN_REF/RSUN_OBS).
1261 + //  (Gauss/pix^2)(CDELT1)^2(RSUN_REF/RSUN_OBS)^2(100.cm/m)^2
1262 + //  =Gauss*cm^2
1263 +
1264 + int computeAbsFlux_los(float *los, int *dims, float *absFlux_los,
1265 +                       float *mean_vf_los_ptr, float *count_mask_los_ptr,
1266 +                       int *bitmask, float cdelt1, double rsun_ref, double rsun_obs)
1267 +
1268 + {
1269      
1270 +    int nx = dims[0];
1271 +    int ny = dims[1];
1272 +    int i = 0;
1273 +    int j = 0;
1274 +    int count_mask_los = 0;
1275 +    double sum = 0.0;
1276 +    *absFlux_los = 0.0;
1277 +    *mean_vf_los_ptr = 0.0;
1278 +    
1279 +    
1280 +    if (nx <= 0 || ny <= 0) return 1;
1281 +    
1282 +        for (i = 0; i < nx; i++)
1283 +        {
1284 +           for (j = 0; j < ny; j++)
1285 +           {
1286 +            if ( bitmask[j * nx + i] < 30 ) continue;
1287 +            if isnan(los[j * nx + i]) continue;
1288 +            sum += (fabs(los[j * nx + i]));
1289 +            count_mask_los++;
1290 +           }
1291 +        }
1292 +    
1293 +    *mean_vf_los_ptr     = sum*cdelt1*cdelt1*(rsun_ref/rsun_obs)*(rsun_ref/rsun_obs)*100.0*100.0;
1294 +    *count_mask_los_ptr  = count_mask_los;
1295 +
1296 +    printf("USFLUXL=%f\n",*mean_vf_los_ptr);
1297 +    printf("CMASKL=%f\n",*count_mask_los_ptr);
1298 +
1299      return 0;
1300   }
1301  
1302 + /*===========================================*/
1303 + /* Example function 18:  Derivative of B_LOS (approximately B_vertical) = SQRT( ( dLOS/dx )^2 + ( dLOS/dy )^2 ) */
1304 +
1305 + int computeLOSderivative(float *los, int *dims, float *mean_derivative_los_ptr, int *bitmask, float *derx_los, float *dery_los)
1306 + {
1307 +    
1308 +    int nx = dims[0];
1309 +    int ny = dims[1];
1310 +    int i = 0;
1311 +    int j = 0;
1312 +    int count_mask = 0;
1313 +    double sum = 0.0;
1314 +    *mean_derivative_los_ptr = 0.0;
1315 +    
1316 +    if (nx <= 0 || ny <= 0) return 1;
1317 +    
1318 +    /* brute force method of calculating the derivative (no consideration for edges) */
1319 +    for (i = 1; i <= nx-2; i++)
1320 +    {
1321 +        for (j = 0; j <= ny-1; j++)
1322 +        {
1323 +           derx_los[j * nx + i] = (los[j * nx + i+1] - los[j * nx + i-1])*0.5;
1324 +        }
1325 +    }
1326 +    
1327 +    /* brute force method of calculating the derivative (no consideration for edges) */
1328 +    for (i = 0; i <= nx-1; i++)
1329 +    {
1330 +        for (j = 1; j <= ny-2; j++)
1331 +        {
1332 +           dery_los[j * nx + i] = (los[(j+1) * nx + i] - los[(j-1) * nx + i])*0.5;
1333 +        }
1334 +    }
1335 +    
1336 +    /* consider the edges for the arrays that contribute to the variable "sum" in the computation below.
1337 +    ignore the edges for the error terms as those arrays have been initialized to zero.
1338 +    this is okay because the error term will ultimately not include the edge pixels as they are selected out by the mask and bitmask arrays.*/
1339 +    i=0;
1340 +    for (j = 0; j <= ny-1; j++)
1341 +    {
1342 +        derx_los[j * nx + i] = ( (-3*los[j * nx + i]) + (4*los[j * nx + (i+1)]) - (los[j * nx + (i+2)]) )*0.5;
1343 +    }
1344 +    
1345 +    i=nx-1;
1346 +    for (j = 0; j <= ny-1; j++)
1347 +    {
1348 +        derx_los[j * nx + i] = ( (3*los[j * nx + i]) + (-4*los[j * nx + (i-1)]) - (-los[j * nx + (i-2)]) )*0.5;
1349 +    }
1350 +    
1351 +    j=0;
1352 +    for (i = 0; i <= nx-1; i++)
1353 +    {
1354 +        dery_los[j * nx + i] = ( (-3*los[j*nx + i]) + (4*los[(j+1) * nx + i]) - (los[(j+2) * nx + i]) )*0.5;
1355 +    }
1356 +    
1357 +    j=ny-1;
1358 +    for (i = 0; i <= nx-1; i++)
1359 +    {
1360 +        dery_los[j * nx + i] = ( (3*los[j * nx + i]) + (-4*los[(j-1) * nx + i]) - (-los[(j-2) * nx + i]) )*0.5;
1361 +    }
1362 +    
1363 +    
1364 +    for (i = 0; i <= nx-1; i++)
1365 +    {
1366 +        for (j = 0; j <= ny-1; j++)
1367 +        {
1368 +            if ( bitmask[j * nx + i] < 30 ) continue;
1369 +            if ( (derx_los[j * nx + i] + dery_los[j * nx + i]) == 0) continue;
1370 +            if isnan(los[j * nx + i])      continue;
1371 +            if isnan(los[(j+1) * nx + i])  continue;
1372 +            if isnan(los[(j-1) * nx + i])  continue;
1373 +            if isnan(los[j * nx + i-1])    continue;
1374 +            if isnan(los[j * nx + i+1])    continue;
1375 +            if isnan(derx_los[j * nx + i]) continue;
1376 +            if isnan(dery_los[j * nx + i]) continue;
1377 +            sum += sqrt( derx_los[j * nx + i]*derx_los[j * nx + i]  + dery_los[j * nx + i]*dery_los[j * nx + i] ); /* Units of Gauss */
1378 +            count_mask++;
1379 +        }
1380 +    }
1381 +    
1382 +    *mean_derivative_los_ptr = (sum)/(count_mask); // would be divided by ((nx-2)*(ny-2)) if shape of count_mask = shape of magnetogram
1383 +    
1384 +    printf("MEANGBL=%f\n",*mean_derivative_los_ptr);
1385 +    
1386 +        return 0;
1387 + }
1388  
1389   /*==================KEIJI'S CODE =========================*/
1390  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines