(file) Return to sharp.c CVS log (file) (dir) Up to [Development] / JSOC / proj / sharp / apps

   1 xudong 1.1 /*
   2             *  sharp.c
   3             *
   4 xudong 1.23  *	This module creates the pipeline Space Weather Active Region Patches (SHARPs).
   5              *	It is a hard-coded strip-down version of bmap.c.
   6              *	It takes the Mharp and Bharp series and create the following quantities:
   7              *
   8              *      Series 1: Sharp_CEA
   9              *	          CEA remapped magnetogram, bitmap, continuum, doppler (same size in map coordinate, need manual spec?)
  10              *	          CEA remapped vector field (Br, Bt, Bp) (same as above)
  11              *                Space weather indices based on vector cutouts (step 2)
  12              *
  13              *      Series 2: Sharp_cutout:
  14              *	          cutouts of magnetogram, bitmap, continuum, doppler (HARP defined, various sizes in CCD pixels)
  15              *	          cutouts of all vector data segments (same as above)
  16 xudong 1.1   *
  17              *	Author:
  18              *		Xudong Sun; Monica Bobra
  19              *
  20              *	Version:
  21 xudong 1.23  *              v0.0 Jul 02 2012
  22              *              v0.1 Jul 23 2012
  23              *              v0.2 Sep 04 2012
  24              *              v0.3 Dec 18 2012
  25              *              v0.4 Jan 02 2013
  26              *              v0.5 Jan 23 2013
  27              *              v0.6 Aug 12 2013
  28              *              v0.7 Jan 02 2014
  29              *              v0.8 Feb 12 2014
  30              *				v0.9 Mar 04 2014
  31 xudong 1.1   *
  32              *	Notes:
  33              *		v0.0
  34              *		Mharp & Bharp must be fully specified; other input are series names only
  35              *		All input records need to match, otherwise quit
  36              *		Mapping parameters depend on keywords of each record only, not necessarily consistent for now
  37              *		Cutout doesn't work for char segments yet (drms_segment_readslice bug)
  38              *		SW indices require ephemeris info which is not passed properly as of now
  39              *		v0.1
  40              *		Fixed char I/O thanks to Art
  41              *		SW indices fixed
  42              *		Added doppler and continuum
  43 xudong 1.3   *              Added other keywords: HEADER (populated by cvs build version), DATE_B
  44 xudong 1.6   *		v0.3
  45              *		Fixed memory leakage of 0.15G per rec; denoted with "Dec 18"
  46 xudong 1.7   *		v0.4
  47              *		Took out convert_inplace(). Was causing all the images to be int
  48 xudong 1.23  *              v0.5
  49              *              Corrected ephemeris keywords, added argument mInfo for setKeys()
  50 xudong 1.17  *		v0.6
  51              *		Changes in remapping of bitmap and conf_disambig, now near neighbor without anti-aliasing
  52 xudong 1.23  *              v0.7
  53              *              Added full disk as "b"
  54              *              Global flag fullDisk is set if "b" is set
  55              *              Utilize BharpRS and BharpRec all around
  56              *              Pass mharpRec to set_keys() too in case of full disk
  57              *              Fixed Bunit (removed from copy_me_keys(), added loops for Bunits in set_keys() here)
  58              *              Error for CEA still does account for disambiguation yet
  59              *		v0.8
  60              *		Added disambig to azimuth during error propagation
  61              *		Changed usage for disambig: bit 2 (radial acute) for full disk, bit 0 for patch
  62              *		Fixed disambig cutout for patch: 0 for even, 7 for odd
  63              *		v0.9
  64              *		Fixed unit
  65              *		Check whether in PATCH of FD mode, so the error propagation uses disambiguated azimuth or not
  66              *
  67              *
  68              *	Example Calls:
  69              *      [I]   B (full disk disambiguation)
  70              *      > sharp "mharp=hmi.Mharp_720s[1832][2012.07.12_15:24]" "b=hmi_test.B_720s[2012.07.12_15:24]" "dop=hmi.V_720s[2012.07.12_15:24]" "cont=hmi.Ic_720s[2012.07.12_15:24]" "sharp_cea=su_xudong.sharp_cea_720s" "sharp_cut=su_xudong.sharp_720s"
  71              *      [II]  BHARP (patch disambiguation)
  72              *      > sharp "mharp=hmi.Mharp_720s[1832][2012.07.12_15:24]" "bharp=hmi.Bharp_720s[1832][2012.07.12_15:24]" "dop=hmi.V_720s[2012.07.12_15:24]" "cont=hmi.Ic_720s[2012.07.12_15:24]" "sharp_cea=su_xudong.sharp_cea_720s" "sharp_cut=su_xudong.sharp_720s"
  73 arta   1.22  *
  74 xudong 1.1   *
  75              */
  76 xudong 1.6  
  77 xudong 1.1  #include <stdio.h>
  78             #include <stdlib.h>
  79             #include <time.h>
  80             #include <sys/time.h>
  81             #include <math.h>
  82             #include <string.h>
  83             #include "jsoc_main.h"
  84             #include "astro.h"
  85             #include "fstats.h"
  86             #include "cartography.c"
  87             #include "fresize.h"
  88             #include "finterpolate.h"
  89             #include "img2helioVector.c"
  90             #include "copy_me_keys.c"
  91             #include "errorprop.c"
  92             #include "sw_functions.c"
  93             
  94 mbobra 1.14 //#include <mkl.h> // Comment out mkl.h, which can only run on solar3
  95 xudong 1.1  #include <mkl_blas.h>
  96             #include <mkl_service.h>
  97             #include <mkl_lapack.h>
  98             #include <mkl_vml_functions.h>
  99             #include <omp.h>
 100 xudong 1.15 
 101 xudong 1.1  #define PI              (M_PI)
 102             #define RADSINDEG		(PI/180.)
 103             #define RAD2ARCSEC		(648000./M_PI)
 104             #define SECINDAY		(86400.)
 105             #define FOURK			(4096)
 106             #define FOURK2    (16777216)
 107             
 108             #define ARRLENGTH(ARR) (sizeof(ARR) / sizeof(ARR[0]))
 109 xudong 1.23 
 110 xudong 1.1  // Nyqvist rate at disk center is 0.03 degree. Oversample above 0.015 degree
 111             #define NYQVIST		(0.015)
 112 xudong 1.23 
 113 mbobra 1.16 // Some other things
 114 xudong 1.1  #ifndef MIN
 115             #define MIN(a,b) (((a)<(b)) ? (a) : (b))
 116             #endif
 117             #ifndef MAX
 118             #define MAX(a,b) (((a)>(b)) ? (a) : (b))
 119             #endif
 120             
 121             #define DIE(msg) {fflush(stdout); fprintf(stderr,"%s, status=%d\n", msg, status); return(status);}
 122             #define SHOW(msg) {printf("%s", msg); fflush(stdout);}
 123             
 124             #define kNotSpecified "Not Specified"
 125 xudong 1.6  
 126 xudong 1.1  // Macros for WCS transformations.  assume crpix1, crpix2 = CRPIX1, CRPIX2, sina,cosa = sin and cos of CROTA2 resp.
 127             // and crvalx and crvaly are CRVAL1 and CRVAL2, cdelt = CDELT1 == CDELT2, then
 128             // PIX_X and PIX_Y are CCD pixel addresses, WX and WY are arc-sec W and N on the Sun from disk center.
 129             #define PIX_X(wx,wy) ((((wx-crvalx)*cosa + (wy-crvaly)*sina)/cdelt)+crpix1)
 130             #define PIX_Y(wx,wy) ((((wy-crvaly)*cosa - (wx-crvalx)*sina)/cdelt)+crpix2)
 131             #define WX(pix_x,pix_y) (((pix_x-crpix1)*cosa - (pix_y-crpix2)*sina)*cdelt+crvalx)
 132             #define WY(pix_x,pix_y) (((pix_y-crpix2)*cosa + (pix_x-crpix1)*sina)*cdelt+crvaly)
 133             
 134             #define DISAMB_AZI		1
 135             #define XSCALE			0.03
 136             #define YSCALE			0.03
 137             #define NBIN			3
 138             #define INTERP			0
 139             #define dpath    "/home/jsoc/cvs/Development/JSOC"
 140             
 141 mbobra 1.16 
 142 xudong 1.1  /* ========================================================================================================== */
 143             
 144             // Space weather keywords
 145             struct swIndex {
 146 xudong 1.23     float mean_vf;
 147 arta   1.22     float count_mask;
 148 xudong 1.1  	float absFlux;
 149             	float mean_hf;
 150             	float mean_gamma;
 151             	float mean_derivative_btotal;
 152 xudong 1.15 	float mean_derivative_bh;
 153 xudong 1.1  	float mean_derivative_bz;
 154             	float mean_jz;
 155             	float us_i;
 156             	float mean_alpha;
 157 xudong 1.23     float mean_ih;
 158                 float total_us_ih;
 159                 float total_abs_ih;
 160                 float totaljz;
 161                 float totpot;
 162                 float meanpot;
 163                 float area_w_shear_gt_45;
 164                 float meanshear_angle;
 165                 float area_w_shear_gt_45h;
 166                 float meanshear_angleh;
 167 arta   1.22     float mean_derivative_btotal_err;
 168                 float mean_vf_err;
 169                 float mean_gamma_err;
 170                 float mean_derivative_bh_err;
 171                 float mean_derivative_bz_err;
 172                 float mean_jz_err;
 173                 float us_i_err;
 174                 float mean_alpha_err;
 175                 float mean_ih_err;
 176                 float total_us_ih_err;
 177                 float total_abs_ih_err;
 178                 float totaljz_err;
 179                 float meanpot_err;
 180                 float totpot_err;
 181                 float meanshear_angle_err;
 182 xudong 1.23     float Rparam;
 183 xudong 1.15 };
 184 xudong 1.1  
 185             // Mapping method
 186             enum projection {
 187             	carree,
 188             	cassini,
 189             	mercator,
 190             	cyleqa,
 191             	sineqa,
 192             	gnomonic,
 193             	postel,
 194             	stereographic,
 195             	orthographic,
 196             	lambert
 197             };
 198             
 199 xudong 1.15 // WSC code
 200             char *wcsCode[] = {"CAR", "CAS", "MER", "CEA", "GLS", "TAN", "ARC", "STG",
 201             	"SIN", "ZEA"};
 202             
 203 mbobra 1.14 // Ephemeris information
 204 xudong 1.1  struct ephemeris {
 205             	double disk_lonc, disk_latc;
 206             	double disk_xc, disk_yc;
 207             	double rSun, asd, pa;
 208             };
 209             
 210             // Mapping information
 211             struct mapInfo {
 212             	float xc, yc;		// reference point: center
 213             	int nrow, ncol;		// size
 214             	float xscale, yscale;	// scale
 215             	int nbin;
 216             	enum projection proj;	// projection method
 217             	struct ephemeris ephem;		// ephemeris info
 218             	float *xi_out, *zeta_out;	// coordinate on full disk image to sample at
 219             };
 220             
 221             /* ========================================================================================================== */
 222             
 223             /* Get all input data series */
 224             int getInputRS(DRMS_RecordSet_t **mharpRS_ptr, DRMS_RecordSet_t **bharpRS_ptr,
 225 xudong 1.1  			   char *mharpQuery, char *bharpQuery);
 226             
 227             /* Check if Mharp and Bharp match */
 228             int compareHarp(DRMS_RecordSet_t *mharpRS, DRMS_RecordSet_t *bharpRS);
 229             
 230             /* Get other data series */
 231             int getInputRS_aux(DRMS_RecordSet_t **inRS_ptr, char *inQuery, DRMS_RecordSet_t *harpRS);
 232             
 233             /* Find record from record set with given T_rec */
 234             int getInputRec_aux(DRMS_Record_t **inRec_ptr, DRMS_RecordSet_t *inRS, TIME trec);
 235             
 236             /* Create CEA record */
 237             int createCeaRecord(DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec,
 238 xudong 1.15 					DRMS_Record_t *dopRec, DRMS_Record_t *contRec,
 239 xudong 1.1  					DRMS_Record_t *sharpRec, struct swIndex *swKeys_ptr);
 240             
 241             /* Mapping single segment, wrapper */
 242             int mapScaler(DRMS_Record_t *sharpRec, DRMS_Record_t *inRec, DRMS_Record_t *harpRec,
 243             			  struct mapInfo *mInfo, char *segName);
 244             
 245             /* Mapping vector magnetogram, wrapper */
 246             int mapVectorB(DRMS_Record_t *sharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo);
 247             
 248             /* Mapping errors of vector magnetogram, wraper */
 249             int mapVectorBErr(DRMS_Record_t *sharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo);
 250             
 251             /* Determine reference point coordinate and patch size according to input */
 252             int findPosition(DRMS_Record_t *inRec, struct mapInfo *mInfo);
 253             
 254             /* Get ephemeris information */
 255             int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem);
 256             
 257             /* Compute the coordinates at which the full disk image is sampled */
 258             void findCoord(struct mapInfo *mInfo);
 259             
 260 xudong 1.1  /* Mapping function */
 261 xudong 1.17 int performSampling(float *outData, float *inData, struct mapInfo *mInfo, int interpOpt);
 262 xudong 1.1  
 263             /* Performing local vector transformation */
 264             void vectorTransform(float *bx_map, float *by_map, float *bz_map, struct mapInfo *mInfo);
 265             
 266             /* Map and propogate errors */
 267             int getBErr(float *bx_err, float *by_err, float *bz_err,
 268 xudong 1.6  			DRMS_Record_t *inRec, struct mapInfo *mInfo);
 269 xudong 1.1  
 270             /* Read full disk vector magnetogram */
 271             int readVectorB(DRMS_Record_t *inRec, float *bx_img, float *by_img, float *bz_img);
 272             
 273             /* Read variances and covariances of vector magnetograms */
 274 xudong 1.15 int readVectorBErr(DRMS_Record_t *bharpRec,
 275 xudong 1.1  				   float *bT, float *bI, float *bA,
 276 xudong 1.15 				   float *errbT, float *errbI, float *errbA,
 277 xudong 1.1  				   float *errbTbI, float *errbTbA, float *errbIbA);
 278             
 279             // ===================
 280             
 281             /* Create Cutout record */
 282             int createCutRecord(DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec,
 283             					DRMS_Record_t *dopRec, DRMS_Record_t *contRec,
 284             					DRMS_Record_t *sharpRec, struct swIndex *swKeys_ptr);
 285             
 286             /* Get cutout and write segment */
 287             int writeCutout(DRMS_Record_t *outRec, DRMS_Record_t *inRec, DRMS_Record_t *harpRec, char *SegName);
 288             
 289             // ===================
 290             
 291             /* Compute space weather indices, no error checking for now */
 292             void computeSWIndex(struct swIndex *swKeys_ptr, DRMS_Record_t *inRec, struct mapInfo *mInfo);
 293             
 294             /* Set space weather indices, no error checking for now */
 295             void setSWIndex(DRMS_Record_t *outRec, struct swIndex *swKeys_ptr);
 296             
 297             /* Set all keywords, no error checking for now */
 298 xudong 1.23 // Changed Dec 30 XS
 299             void setKeys(DRMS_Record_t *outRec, DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo);
 300 xudong 1.1  
 301             // ===================
 302             
 303             /* Nearest neighbor interpolation */
 304             float nnb (float *f, int nx, int ny, double x, double y);
 305             
 306             /* Wrapper for Jesper's rebin code */
 307             void frebin (float *image_in, float *image_out, int nx, int ny, int nbin, int gauss);
 308             
 309             /* ========================================================================================================== */
 310             
 311             /* Remap segment names */
 312             #define BR_SEG_CEA		"Br"
 313             #define BT_SEG_CEA		"Bt"
 314             #define BP_SEG_CEA		"Bp"
 315             #define BR_ERR_SEG_CEA		"Br_err"
 316             #define BT_ERR_SEG_CEA		"Bt_err"
 317             #define BP_ERR_SEG_CEA		"Bp_err"
 318             
 319             /* Cutout segment names, input identical to output */
 320             char *MharpSegs[] = {"magnetogram", "bitmap"};
 321 xudong 1.1  char *BharpSegs[] = {"inclination", "azimuth", "field", "vlos_mag", "dop_width", "eta_0",
 322             	"damping", "src_continuum", "src_grad", "alpha_mag", "chisq",
 323             	"conv_flag", // fixed
 324             	"info_map", "confid_map",
 325             	"inclination_err", "azimuth_err", "field_err", "vlos_err", "alpha_err",
 326             	"field_inclination_err", "field_az_err", "inclin_azimuth_err",
 327             	"field_alpha_err","inclination_alpha_err", "azimuth_alpha_err",
 328             	"disambig", "conf_disambig"};
 329             // For stats
 330 xudong 1.15 char *CutSegs[] = {"magnetogram", "bitmap", "Dopplergram", "continuum",
 331 xudong 1.1  	"inclination", "azimuth", "field", "vlos_mag", "dop_width", "eta_0",
 332             	"damping", "src_continuum", "src_grad", "alpha_mag", "chisq",
 333             	"conv_flag", // fixed
 334             	"info_map", "confid_map",
 335             	"inclination_err", "azimuth_err", "field_err", "vlos_err", "alpha_err",
 336             	"field_inclination_err", "field_az_err", "inclin_azimuth_err",
 337             	"field_alpha_err","inclination_alpha_err", "azimuth_alpha_err",
 338             	"disambig", "conf_disambig"};
 339 xudong 1.23 char *CEASegs[] = {"magnetogram", "bitmap", "Dopplergram", "continuum",
 340             	BR_SEG_CEA, BT_SEG_CEA, BP_SEG_CEA, BR_ERR_SEG_CEA, BT_ERR_SEG_CEA, BP_ERR_SEG_CEA, "conf_disambig"};
 341             // For Bunits, added Dec 30 XS
 342             char *CutBunits[] = {"Mx/cm^2", " ", "cm/s", "DN/s",
 343                 "degree", "degree", "Mx/cm^2", "cm/s", "mA", " ",
 344                 "length units", "DN/s", "DN/s", " ", " ",
 345                 " ",
 346                 " ", " ",
 347                 "degree", "degree", "Mx/cm^2", "cm/s", " ",
 348                 " ", " ", " ",
 349                 " ", " ", " ",
 350                 " ", " "};
 351             char *CEABunits[] = {"Mx/cm^2", " ", "cm/s", "DN/s",
 352                 "Mx/cm^2", "Mx/cm^2", "Mx/cm^2", "Mx/cm^2", "Mx/cm^2", "Mx/cm^2", " "};      // Mar 4 2014 XS
 353 xudong 1.15 
 354 xudong 1.1  /* ========================================================================================================== */
 355             
 356             char *module_name = "sharp";
 357 mbobra 1.14 int seed;
 358 xudong 1.1  
 359 xudong 1.23 int fullDisk;       // full disk mode
 360             int amb4err;      // Use azimuth disambiguation for error propagation, default is 0 for patch and 1 for FD
 361             
 362 xudong 1.1  ModuleArgs_t module_args[] =
 363             {
 364             	{ARG_STRING, "mharp", kNotSpecified, "Input Mharp series."},
 365             	{ARG_STRING, "bharp", kNotSpecified, "Input Bharp series."},
 366 xudong 1.23     {ARG_STRING, "b", kNotSpecified, "Input B series, if set, overrides bharp."},
 367 xudong 1.1  	{ARG_STRING, "dop", kNotSpecified, "Input Doppler series."},
 368             	{ARG_STRING, "cont", kNotSpecified, "Input Continuum series."},
 369             	{ARG_STRING, "sharp_cea", kNotSpecified, "Output Sharp CEA series."},
 370             	{ARG_STRING, "sharp_cut", kNotSpecified, "Output Sharp cutout series."},
 371 xudong 1.15     {ARG_INT,    "seed", "987654", "Seed for the random number generator."},
 372 xudong 1.23     {ARG_INT,   "f_amb4err", "0", "Force using disambiguation in error propagation"},     // Mar 4 2014 XS
 373 xudong 1.1  	{ARG_END}
 374             };
 375             
 376 xudong 1.15 int DoIt(void)
 377 xudong 1.1  {
 378 xudong 1.23     int errbufstat = setvbuf(stderr, NULL, _IONBF, BUFSIZ);
 379                 int outbufstat = setvbuf(stdout, NULL, _IONBF, BUFSIZ);
 380 xudong 1.15     
 381 xudong 1.1  	int status = DRMS_SUCCESS;
 382             	int nrecs, irec;
 383             	
 384 xudong 1.23 	char *mharpQuery, *bharpQuery, *bQuery;
 385 xudong 1.1  	char *dopQuery, *contQuery;
 386             	char *sharpCeaQuery, *sharpCutQuery;
 387             	
 388             	DRMS_RecordSet_t *mharpRS = NULL, *bharpRS = NULL;
 389             	DRMS_RecordSet_t *dopRS = NULL, *contRS = NULL;
 390             	
 391             	/* Get parameters */
 392                 
 393             	mharpQuery = (char *) params_get_str(&cmdparams, "mharp");
 394             	bharpQuery = (char *) params_get_str(&cmdparams, "bharp");
 395 xudong 1.23     bQuery = (char *) params_get_str(&cmdparams, "b");
 396 xudong 1.1  	dopQuery = (char *) params_get_str(&cmdparams, "dop");
 397             	contQuery = (char *) params_get_str(&cmdparams, "cont");
 398             	sharpCeaQuery = (char *) params_get_str(&cmdparams, "sharp_cea");
 399             	sharpCutQuery = (char *) params_get_str(&cmdparams, "sharp_cut");
 400 xudong 1.15     
 401                 seed = params_get_int(&cmdparams, "seed");
 402 xudong 1.23     int f_amb4err = params_get_int(&cmdparams, "f_amb4err");
 403 xudong 1.1  	
 404             	/* Get input data, check everything */
 405             	
 406 xudong 1.23     // Full disk mode if "b" is set
 407                 if (strcmp(bQuery, kNotSpecified)) {
 408                     fullDisk = 1;
 409                     bharpQuery = bQuery;
 410                     //        SHOW(bharpQuery); SHOW("\n");
 411                     SHOW("Full disk mode\n");
 412                 } else {
 413                     fullDisk = 0;
 414                     SHOW("Harp mode\n");
 415                 }
 416                 
 417                 // Mar 4 2014
 418                 if (f_amb4err == 0) {         // no forcing, 0 for patch and 1 for FD
 419                     amb4err = fullDisk ? 1 : 0;
 420                 } else {
 421                     amb4err = 1;
 422                 }
 423                 printf("amb4err=%d\n", amb4err);
 424                 
 425                 // Bharp point to B if full disk
 426                 if (getInputRS(&mharpRS, &bharpRS, mharpQuery, bharpQuery))
 427 xudong 1.23         DIE("Input harp data error.");
 428 xudong 1.1  	nrecs = mharpRS->n;
 429             	
 430 xudong 1.15 	if (getInputRS_aux(&dopRS, dopQuery, mharpRS))
 431 xudong 1.1  		DIE("Input doppler data error.");
 432             	
 433 xudong 1.15 	if (getInputRS_aux(&contRS, contQuery, mharpRS))
 434 xudong 1.1  		DIE("Input continuum data error.");
 435             	
 436             	/* Start */
 437             	
 438             	printf("==============\nStart. %d image(s) in total.\n", nrecs);
 439 xudong 1.15     
 440 xudong 1.1  	for (irec = 0; irec < nrecs; irec++) {
 441             		
 442             		/* Records in work */
 443             		
 444             		DRMS_Record_t *mharpRec = NULL, *bharpRec = NULL;
 445 xudong 1.23         
 446 xudong 1.1  		mharpRec = mharpRS->records[irec];
 447 xudong 1.23         
 448                     TIME trec = drms_getkey_time(mharpRec, "T_REC", &status);
 449                     
 450             		if (!fullDisk) {
 451                         bharpRec = bharpRS->records[irec];
 452                     } else {
 453                         if (getInputRec_aux(&bharpRec, bharpRS, trec)) {     // Bharp point to full disk B
 454                             printf("Fetching B failed, image #%d skipped.\n", irec);
 455                             continue;
 456                         }
 457                     }
 458                     
 459 xudong 1.1  		struct swIndex swKeys;
 460             		
 461             		DRMS_Record_t *dopRec = NULL, *contRec = NULL;
 462 xudong 1.23         
 463 xudong 1.1  		if (getInputRec_aux(&dopRec, dopRS, trec)) {
 464             			printf("Fetching Doppler failed, image #%d skipped.\n", irec);
 465             			continue;
 466             		}
 467             		if (getInputRec_aux(&contRec, contRS, trec)) {
 468             			printf("Fetching continuum failed, image #%d skipped.\n", irec);
 469             			continue;
 470             		}
 471 xudong 1.15         
 472 xudong 1.1  		/* Create CEA record */
 473             		
 474             		DRMS_Record_t *sharpCeaRec = drms_create_record(drms_env, sharpCeaQuery, DRMS_PERMANENT, &status);
 475             		if (status) {		// if failed
 476             			printf("Creating CEA failed, image #%d skipped.\n", irec);
 477             			continue;
 478             		}
 479             		
 480             		if (createCeaRecord(mharpRec, bharpRec, dopRec, contRec, sharpCeaRec, &swKeys)) {		// do the work
 481             			printf("Creating CEA failed, image #%d skipped.\n", irec);
 482             			drms_close_record(sharpCeaRec, DRMS_FREE_RECORD);
 483             			continue;
 484             		}		// swKeys updated here
 485             		
 486             		drms_close_record(sharpCeaRec, DRMS_INSERT_RECORD);
 487             		
 488             		/* Create Cutout record */
 489             		
 490             		DRMS_Record_t *sharpCutRec = drms_create_record(drms_env, sharpCutQuery, DRMS_PERMANENT, &status);
 491             		if (status) {		// if failed
 492             			printf("Creating cutout failed, image #%d skipped.\n", irec);
 493 xudong 1.1  			continue;
 494             		}
 495             		
 496             		if (createCutRecord(mharpRec, bharpRec, dopRec, contRec, sharpCutRec, &swKeys)) {		// do the work
 497             			printf("Creating cutout failed, image #%d skipped.\n", irec);
 498             			drms_close_record(sharpCutRec, DRMS_FREE_RECORD);
 499             			continue;
 500             		}		// swKeys used here
 501             		
 502             		drms_close_record(sharpCutRec, DRMS_INSERT_RECORD);
 503             		
 504             		/* Done */
 505             		
 506             		printf("Image #%d done.\n", irec);
 507             		
 508             	} // irec
 509 xudong 1.15     
 510 xudong 1.1  	
 511             	drms_close_records(mharpRS, DRMS_FREE_RECORD);
 512             	drms_close_records(bharpRS, DRMS_FREE_RECORD);
 513 xudong 1.6  	drms_close_records(dopRS, DRMS_FREE_RECORD);				// Dec 18 2012
 514             	drms_close_records(contRS, DRMS_FREE_RECORD);				// Dec 18 2012
 515 xudong 1.1  	
 516             	return 0;
 517 xudong 1.6  	
 518 xudong 1.1  }	// DoIt
 519             
 520             
 521             // ===================================================================
 522             // ===================================================================
 523             // ===================================================================
 524             
 525             
 526             /*
 527              * Get input data series, including mHarp and bharp
 528              * Need all records to match, otherwise quit
 529              *
 530              */
 531             
 532             int getInputRS(DRMS_RecordSet_t **mharpRS_ptr, DRMS_RecordSet_t **bharpRS_ptr,
 533             			   char *mharpQuery, char *bharpQuery)
 534             {
 535             	
 536             	int status = 0;
 537             	
 538             	*mharpRS_ptr = drms_open_records(drms_env, mharpQuery, &status);
 539 xudong 1.1      if (status || (*mharpRS_ptr)->n == 0) return 1;
 540             	
 541 xudong 1.23 	if (fullDisk) {
 542                     if (getInputRS_aux(bharpRS_ptr, bharpQuery, *mharpRS_ptr)) return 1;
 543                 } else {
 544                     *bharpRS_ptr = drms_open_records(drms_env, bharpQuery, &status);
 545                     if (status || (*bharpRS_ptr)->n == 0) return 1;
 546                     if (compareHarp((*mharpRS_ptr), (*bharpRS_ptr))) return 1;
 547                 }
 548 xudong 1.1  	
 549             	return 0;
 550             	
 551             }
 552             
 553             /*
 554              * Check if Mharp and Bharp match
 555              *
 556              */
 557             
 558             int compareHarp(DRMS_RecordSet_t *mharpRS, DRMS_RecordSet_t *bharpRS)
 559             {
 560             	
 561             	int status = 0;
 562             	int nrecs = mharpRS->n;
 563             	
 564             	DRMS_Record_t *mharpRec_t = NULL, *bharpRec_t = NULL;		// temporary recs for utility
 565             	
 566                 if (bharpRS->n != nrecs) {
 567             		return 1;		// return 1 if different
 568             	}
 569 xudong 1.1  	
 570             	for (int i = 0; i < nrecs; i++) {
 571             		mharpRec_t = mharpRS->records[i];
 572             		bharpRec_t = bharpRS->records[i];
 573 xudong 1.15 		if ((drms_getkey_int(mharpRec_t, "HARPNUM", &status) !=
 574 xudong 1.1  			 drms_getkey_int(bharpRec_t, "HARPNUM", &status)) ||
 575 xudong 1.15 			(drms_getkey_time(mharpRec_t, "T_REC", &status) !=
 576 xudong 1.1  			 drms_getkey_time(bharpRec_t, "T_REC", &status)))
 577             		{
 578             			return 1;
 579             		}
 580             	}
 581             	
 582             	return 0;
 583             	
 584             }
 585             
 586 xudong 1.15 /*
 587 xudong 1.1   * Get other data series, check all T_REC are available
 588              *
 589              */
 590             
 591             int getInputRS_aux(DRMS_RecordSet_t **inRS_ptr, char *inQuery, DRMS_RecordSet_t *harpRS)
 592             {
 593             	
 594             	int status = 0;
 595             	
 596             	*inRS_ptr = drms_open_records(drms_env, inQuery, &status);
 597             	if (status || (*inRS_ptr)->n == 0) return status;
 598             	
 599             	// Check if all T_rec are available, need to match both ways
 600             	int n = harpRS->n, n0 = (*inRS_ptr)->n;
 601 xudong 1.6  	
 602 xudong 1.1  	for (int i0 = 0; i0 < n0; i0++) {
 603             		DRMS_Record_t *inRec = (*inRS_ptr)->records[i0];
 604             		TIME trec0 = drms_getkey_time(inRec, "T_REC", &status);
 605             		TIME trec = 0;
 606             		for (int i = 0; i < n; i++) {
 607             			DRMS_Record_t *harpRec = harpRS->records[i];
 608             			trec = drms_getkey_time(harpRec, "T_REC", &status);
 609             			if (fabs(trec0 - trec) < 10) break;
 610             		}
 611             		if (fabs(trec0 - trec) >= 10) return 1;
 612             	}
 613             	
 614             	for (int i = 0; i < n; i++) {
 615             		DRMS_Record_t *harpRec = harpRS->records[i];
 616             		TIME trec = drms_getkey_time(harpRec, "T_REC", &status);
 617             		TIME trec0 = 0;
 618             		for (int i0 = 0; i0 < n0; i0++) {
 619             			DRMS_Record_t *inRec = (*inRS_ptr)->records[i0];
 620             			trec0 = drms_getkey_time(inRec, "T_REC", &status);
 621             			if (fabs(trec0 - trec) < 10) break;
 622             		}
 623 xudong 1.1  		if (fabs(trec0 - trec) >= 10) return 1;
 624             	}
 625             	
 626             	return 0;
 627             	
 628             }
 629             
 630 xudong 1.15 /*
 631 xudong 1.1   * Find record from record set with given T_rec
 632              *
 633              */
 634             
 635             int getInputRec_aux(DRMS_Record_t **inRec_ptr, DRMS_RecordSet_t *inRS, TIME trec)
 636             {
 637             	
 638             	int status = 0;
 639             	
 640             	int n = inRS->n;
 641             	for (int i = 0; i < n; i++) {
 642             		*inRec_ptr = inRS->records[i];
 643             		TIME trec0 = drms_getkey_time((*inRec_ptr), "T_REC", &status);
 644             		if (fabs(trec0 - trec) < 10) return 0;
 645             	}
 646             	
 647             	return 1;
 648             	
 649             }
 650             
 651             
 652 xudong 1.1  
 653             
 654             /*
 655              * Create CEA record: top level subroutine
 656              * Also compute all the space weather keywords here
 657              *
 658              */
 659             
 660 xudong 1.15 int createCeaRecord(DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec,
 661             					DRMS_Record_t *dopRec, DRMS_Record_t *contRec,
 662 xudong 1.1  					DRMS_Record_t *sharpRec, struct swIndex *swKeys_ptr)
 663             {
 664             	
 665             	int status = 0;
 666             	DRMS_Segment_t *inSeg;
 667             	DRMS_Array_t *inArray;
 668             	
 669             	struct mapInfo mInfo;
 670             	mInfo.proj = (enum projection) cyleqa;		// projection method
 671             	mInfo.xscale = XSCALE;
 672             	mInfo.yscale = YSCALE;
 673 xudong 1.17 	
 674 xudong 1.23     int ncol0, nrow0;		// oversampled map size
 675 xudong 1.1  	
 676             	// Get ephemeris
 677 xudong 1.6  	
 678 xudong 1.3  	if (getEphemeris(mharpRec, &(mInfo.ephem))) {
 679             		SHOW("CEA: get ephemeris error\n");
 680             		return 1;
 681             	}
 682 xudong 1.1  	
 683             	// Find position
 684             	
 685 xudong 1.3  	if (findPosition(mharpRec, &mInfo)) {
 686             		SHOW("CEA: find position error\n");
 687             		return 1;
 688             	}
 689 xudong 1.1  	
 690 xudong 1.17 	// ========================================
 691             	// Do this for all bitmaps, Aug 12 2013 XS
 692             	// ========================================
 693             	
 694 xudong 1.23     mInfo.nbin = 1;			// for bitmaps. suppress anti-aliasing
 695 xudong 1.17 	ncol0 = mInfo.ncol;
 696             	nrow0 = mInfo.nrow;
 697             	
 698             	mInfo.xi_out = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
 699             	mInfo.zeta_out = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
 700             	
 701             	findCoord(&mInfo);		// compute it here so it could be shared by the following 4 functions
 702             	
 703             	if (mapScaler(sharpRec, mharpRec, mharpRec, &mInfo, "bitmap")) {
 704             		SHOW("CEA: mapping bitmap error\n");
 705             		return 1;
 706             	}
 707             	printf("Bitmap mapping done.\n");
 708             	
 709 xudong 1.23     if (mapScaler(sharpRec, bharpRec, mharpRec, &mInfo, "conf_disambig")) {
 710 xudong 1.17 		SHOW("CEA: mapping conf_disambig error\n");
 711             		return 1;
 712             	}
 713             	printf("Conf disambig mapping done.\n");
 714             	
 715 xudong 1.23     free(mInfo.xi_out);
 716 xudong 1.17 	free(mInfo.zeta_out);
 717             	
 718             	// ========================================
 719             	// Do this again for floats, Aug 12 2013 XS
 720             	// ========================================
 721 xudong 1.1  	// Create xi_out, zeta_out array in mInfo:
 722             	// Coordinates to sample in original full disk image
 723             	
 724 xudong 1.17 	mInfo.nbin = NBIN;
 725 xudong 1.1  	ncol0 = mInfo.ncol * mInfo.nbin + (mInfo.nbin / 2) * 2;	// pad with nbin/2 on edge to avoid NAN
 726             	nrow0 = mInfo.nrow * mInfo.nbin + (mInfo.nbin / 2) * 2;
 727             	
 728             	mInfo.xi_out = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
 729             	mInfo.zeta_out = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
 730             	
 731             	findCoord(&mInfo);		// compute it here so it could be shared by the following 4 functions
 732             	
 733             	// Mapping single segment: Mharp, etc.
 734 xudong 1.15     
 735 xudong 1.3  	if (mapScaler(sharpRec, mharpRec, mharpRec, &mInfo, "magnetogram")) {
 736             		SHOW("CEA: mapping magnetogram error\n");
 737             		return 1;
 738             	}
 739 xudong 1.1  	printf("Magnetogram mapping done.\n");
 740 xudong 1.23     
 741 xudong 1.3  	if (mapScaler(sharpRec, dopRec, mharpRec, &mInfo, "Dopplergram")) {
 742             		SHOW("CEA: mapping dopplergram error\n");
 743             		return 1;
 744             	}
 745 xudong 1.1  	printf("Dopplergram mapping done.\n");
 746             	
 747 xudong 1.3  	if (mapScaler(sharpRec, contRec, mharpRec, &mInfo, "continuum")) {
 748             		SHOW("CEA: mapping continuum error\n");
 749             		return 1;
 750             	}
 751 xudong 1.1  	printf("Intensitygram mapping done.\n");
 752 xudong 1.6  	
 753 xudong 1.1  	// Mapping vector B
 754             	
 755 xudong 1.3  	if (mapVectorB(sharpRec, bharpRec, &mInfo)) {
 756             		SHOW("CEA: mapping vector B error\n");
 757             		return 1;
 758             	}
 759 xudong 1.1  	printf("Vector B mapping done.\n");
 760             	
 761             	// Mapping vector B errors
 762             	
 763 xudong 1.3  	if (mapVectorBErr(sharpRec, bharpRec, &mInfo)) {
 764             		SHOW("CEA: mapping vector B uncertainty error\n");
 765             		return 1;
 766             	}
 767 xudong 1.1  	printf("Vector B error done.\n");
 768             	
 769             	// Keywords & Links
 770             	
 771             	drms_copykey(sharpRec, mharpRec, "T_REC");
 772             	drms_copykey(sharpRec, mharpRec, "HARPNUM");
 773             	
 774 xudong 1.23     if (fullDisk) {
 775                     DRMS_Link_t *bLink = hcon_lookup_lower(&sharpRec->links, "B");
 776                     if (bLink) drms_link_set("B", sharpRec, bharpRec);
 777                 } else {
 778                     DRMS_Link_t *bHarpLink = hcon_lookup_lower(&sharpRec->links, "BHARP");
 779                     if (bHarpLink) drms_link_set("BHARP", sharpRec, bharpRec);
 780                 }
 781 xudong 1.1  	DRMS_Link_t *mHarpLink = hcon_lookup_lower(&sharpRec->links, "MHARP");
 782             	if (mHarpLink) drms_link_set("MHARP", sharpRec, mharpRec);
 783             	
 784 xudong 1.23     setKeys(sharpRec, mharpRec, bharpRec, &mInfo);            // Set all other keywords
 785 xudong 1.3  	drms_copykey(sharpRec, mharpRec, "QUALITY");		// copied from los records
 786 xudong 1.6  	
 787 xudong 1.1  	// Space weather
 788             	
 789             	computeSWIndex(swKeys_ptr, sharpRec, &mInfo);		// compute it!
 790             	printf("Space weather indices done.\n");
 791             	
 792             	setSWIndex(sharpRec, swKeys_ptr);	// Set space weather indices
 793 xudong 1.6  	
 794 xudong 1.1  	// Stats
 795             	
 796             	int nCEASegs = ARRLENGTH(CEASegs);
 797             	for (int iSeg = 0; iSeg < nCEASegs; iSeg++) {
 798             		DRMS_Segment_t *outSeg = drms_segment_lookupnum(sharpRec, iSeg);
 799             		DRMS_Array_t *outArray = drms_segment_read(outSeg, DRMS_TYPE_FLOAT, &status);
 800             		int stat = set_statistics(outSeg, outArray, 1);
 801 xudong 1.6  		//		printf("%d => %d\n", iSeg, stat);
 802 xudong 1.1  		drms_free_array(outArray);
 803             	}
 804             	
 805             	free(mInfo.xi_out);
 806             	free(mInfo.zeta_out);
 807             	return 0;
 808             	
 809             }
 810             
 811             
 812 xudong 1.15 /*
 813 xudong 1.1   * Mapping a single segment
 814              * Read in full disk image, utilize mapImage for mapping
 815              * then write the segment out, segName same in in/out Rec
 816              *
 817              */
 818             
 819             int mapScaler(DRMS_Record_t *sharpRec, DRMS_Record_t *inRec, DRMS_Record_t *harpRec,
 820             			  struct mapInfo *mInfo, char *segName)
 821             {
 822             	
 823             	int status = 0;
 824             	int nx = mInfo->ncol, ny = mInfo->nrow, nxny = nx * ny;
 825             	int dims[2] = {nx, ny};
 826 xudong 1.17 	int interpOpt = INTERP;		// Aug 12 XS, default, overridden below for bitmaps and conf_disambig
 827 xudong 1.1  	
 828             	// Input full disk array
 829             	
 830             	DRMS_Segment_t *inSeg = NULL;
 831             	inSeg = drms_segment_lookup(inRec, segName);
 832             	if (!inSeg) return 1;
 833             	
 834             	DRMS_Array_t *inArray = NULL;
 835             	inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
 836             	if (!inArray) return 1;
 837             	
 838 xudong 1.23     if (!strcmp(segName, "conf_disambig") || !strcmp(segName, "bitmap")) {
 839                     // Moved out so it works for FD conf_disambig as well
 840                     // Jan 2 2014 XS
 841                     interpOpt = 3;		// Aug 12 XS, near neighbor
 842                 }
 843                 
 844 xudong 1.1  	float *inData;
 845             	int xsz = inArray->axis[0], ysz = inArray->axis[1];
 846             	if ((xsz != FOURK) || (ysz != FOURK)) {		// for bitmap, make tmp full disk
 847             		float *inData0 = (float *) inArray->data;
 848             		inData = (float *) (calloc(FOURK2, sizeof(float)));
 849             		int x0 = (int) drms_getkey_float(harpRec, "CRPIX1", &status) - 1;
 850             		int y0 = (int) drms_getkey_float(harpRec, "CRPIX2", &status) - 1;
 851             		int ind_map;
 852             		for (int row = 0; row < ysz; row++) {
 853             			for (int col = 0; col < xsz; col++) {
 854             				ind_map = (row + y0) * FOURK + (col + x0);
 855             				inData[ind_map] = inData0[row * xsz + col];
 856             			}
 857             		}
 858             		drms_free_array(inArray); inArray = NULL;
 859             	} else {
 860             		inData = (float *) inArray->data;
 861             	}
 862             	
 863             	// Mapping
 864             	
 865 xudong 1.1  	float *map = (float *) (malloc(nxny * sizeof(float)));
 866 xudong 1.17 	if (performSampling(map, inData, mInfo, interpOpt))		// Add interpOpt for different types, Aug 12 XS
 867 xudong 1.6  	{if (inArray) drms_free_array(inArray); free(map); return 1;}
 868 xudong 1.1  	
 869             	// Write out
 870             	
 871 xudong 1.15 	DRMS_Segment_t *outSeg = NULL;
 872 xudong 1.1  	outSeg = drms_segment_lookup(sharpRec, segName);
 873             	if (!outSeg) return 1;
 874             	
 875 xudong 1.15     //	DRMS_Type_t arrayType = outSeg->info->type;
 876 xudong 1.1  	DRMS_Array_t *outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, map, &status);
 877             	if (status) {if (inArray) drms_free_array(inArray); free(map); return 1;}
 878             	
 879             	// convert to needed data type
 880             	
 881 xudong 1.15     //	drms_array_convert_inplace(outSeg->info->type, 0, 1, outArray);		// Jan 02 2013
 882 xudong 1.1  	
 883             	outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
 884 xudong 1.15     //	outArray->parent_segment = outSeg;
 885 xudong 1.8  	outArray->israw = 0;		// always compressed
 886 xudong 1.1  	outArray->bzero = outSeg->bzero;
 887             	outArray->bscale = outSeg->bscale;
 888 xudong 1.6  	
 889 xudong 1.1  	status = drms_segment_write(outSeg, outArray, 0);
 890             	if (status) return 0;
 891             	
 892             	if (inArray) drms_free_array(inArray);
 893 xudong 1.6  	if ((xsz != FOURK) || (ysz != FOURK)) free(inData);			// Dec 18 2012
 894 xudong 1.1  	if (outArray) drms_free_array(outArray);
 895             	return 0;
 896             	
 897             }
 898             
 899             
 900 xudong 1.15 /*
 901 xudong 1.1   * Mapping vector magnetogram
 902              *
 903              */
 904             
 905             int mapVectorB(DRMS_Record_t *sharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo)
 906             {
 907             	
 908             	int status = 0;
 909             	int nx = mInfo->ncol, ny = mInfo->nrow, nxny = nx * ny;
 910             	int dims[2] = {nx, ny};
 911             	
 912             	// Read in segments, filling factor assume to be 1
 913             	
 914             	float *bx_img = (float *) (malloc(FOURK2 * sizeof(float)));
 915             	float *by_img = (float *) (malloc(FOURK2 * sizeof(float)));
 916             	float *bz_img = (float *) (malloc(FOURK2 * sizeof(float)));
 917             	
 918             	if (readVectorB(bharpRec, bx_img, by_img, bz_img)) {
 919             		printf("Read full disk image error\n");
 920             		free(bx_img); free(by_img); free(bz_img);
 921             		return 1;
 922 xudong 1.1  	}
 923             	
 924             	// Mapping
 925             	
 926             	float *bx_map = NULL, *by_map = NULL, *bz_map = NULL;	// intermediate maps, in CCD bxyz representation
 927 xudong 1.6  	
 928 xudong 1.1  	bx_map = (float *) (malloc(nxny * sizeof(float)));
 929 xudong 1.17 	if (performSampling(bx_map, bx_img, mInfo, INTERP))
 930 xudong 1.6  	{free(bx_img); free(by_img); free(bz_img); free(bx_map); return 1;}
 931             	
 932 xudong 1.1  	by_map = (float *) (malloc(nxny * sizeof(float)));
 933 xudong 1.17 	if (performSampling(by_map, by_img, mInfo, INTERP))
 934 xudong 1.6  	{free(bx_img); free(by_img); free(bz_img); free(bz_map); return 1;}
 935             	
 936 xudong 1.1  	bz_map = (float *) (malloc(nxny * sizeof(float)));
 937 xudong 1.17 	if (performSampling(bz_map, bz_img, mInfo, INTERP))
 938 xudong 1.6  	{free(bx_img); free(by_img); free(bz_img); free(bz_map); return 1;}
 939 xudong 1.1  	
 940             	free(bx_img); free(by_img); free(bz_img);
 941             	
 942             	// Vector transform
 943             	
 944             	vectorTransform(bx_map, by_map, bz_map, mInfo);
 945             	
 946             	for (int i = 0; i < nxny; i++) by_map[i] *= -1;		// positive theta pointing south
 947             	
 948             	// Write out
 949             	
 950             	DRMS_Segment_t *outSeg;
 951             	DRMS_Array_t *outArray;
 952             	
 953             	float *data_prt[3] = {bx_map, by_map, bz_map};
 954             	char *segName[3] = {BP_SEG_CEA, BT_SEG_CEA, BR_SEG_CEA};
 955             	
 956             	for (int iSeg = 0; iSeg < 3; iSeg++) {
 957             		outSeg = drms_segment_lookup(sharpRec, segName[iSeg]);
 958             		outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, data_prt[iSeg], &status);
 959             		outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
 960 xudong 1.15         //		outArray->parent_segment = outSeg;
 961 xudong 1.8  		outArray->israw = 0;
 962 xudong 1.1  		outArray->bzero = outSeg->bzero;
 963             		outArray->bscale = outSeg->bscale;
 964             		status = drms_segment_write(outSeg, outArray, 0);
 965             		if (status) return 1;
 966             		drms_free_array(outArray);
 967             	}
 968             	
 969             	//
 970             	
 971             	return 0;
 972             	
 973             }
 974             
 975             
 976 xudong 1.15 /*
 977 xudong 1.1   * Mapping vector magnetogram errors
 978              *
 979              */
 980             
 981             int mapVectorBErr(DRMS_Record_t *sharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo)
 982             {
 983             	
 984             	int status = 0;
 985             	
 986             	int nx = mInfo->ncol, ny = mInfo->nrow, nxny = nx * ny;
 987             	int dims[2] = {nx, ny};
 988             	
 989             	// Compute propogated errors, using nearest neighbour interpolation
 990             	
 991             	float *bx_err = (float *) (malloc(nxny * sizeof(float)));
 992             	float *by_err = (float *) (malloc(nxny * sizeof(float)));
 993             	float *bz_err = (float *) (malloc(nxny * sizeof(float)));
 994             	
 995             	if (getBErr(bx_err, by_err, bz_err, bharpRec, mInfo)) {
 996             		free(bx_err); free(by_err); free(bz_err);
 997             		return 1;
 998 xudong 1.1  	}
 999 xudong 1.6  	
1000 xudong 1.1  	// Write out
1001             	
1002             	DRMS_Segment_t *outSeg;
1003             	DRMS_Array_t *outArray;
1004             	
1005             	float *data_prt[3] = {bx_err, by_err, bz_err};
1006             	char *segName[3] = {BP_ERR_SEG_CEA, BT_ERR_SEG_CEA, BR_ERR_SEG_CEA};
1007             	
1008             	for (int iSeg = 0; iSeg < 3; iSeg++) {
1009             		outSeg = drms_segment_lookup(sharpRec, segName[iSeg]);
1010             		outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, data_prt[iSeg], &status);
1011             		outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
1012 xudong 1.15         //		outArray->parent_segment = outSeg;
1013 xudong 1.8  		outArray->israw = 0;
1014 xudong 1.1  		outArray->bzero = outSeg->bzero;
1015             		outArray->bscale = outSeg->bscale;
1016             		status = drms_segment_write(outSeg, outArray, 0);
1017             		if (status) return 1;
1018             		drms_free_array(outArray);
1019             	}
1020             	
1021             	//
1022             	
1023             	return 0;
1024             	
1025             }
1026             
1027             
1028             
1029 xudong 1.15 /*
1030 xudong 1.1   * Determine reference point coordinate and patch size according to keywords
1031              * xc, yc are the coordinate of patch center, in degrees
1032              * ncol and nrow are the final size
1033              *
1034              */
1035             
1036             int findPosition(DRMS_Record_t *inRec, struct mapInfo *mInfo)
1037             {
1038             	
1039             	int status = 0;
1040             	int harpnum = drms_getkey_int(inRec, "HARPNUM", &status);
1041             	TIME trec = drms_getkey_time(inRec, "T_REC", &status);
1042             	float disk_lonc = drms_getkey_float(inRec, "CRLN_OBS", &status);
1043             	
1044             	/* Center coord */
1045             	
1046             	float minlon = drms_getkey_float(inRec, "LONDTMIN", &status); if (status) return 1;		// Stonyhurst lon
1047             	float maxlon = drms_getkey_float(inRec, "LONDTMAX", &status); if (status) return 1;
1048             	float minlat = drms_getkey_float(inRec, "LATDTMIN", &status); if (status) return 1;
1049             	float maxlat = drms_getkey_float(inRec, "LATDTMAX", &status); if (status) return 1;
1050             	
1051 xudong 1.1  	// A bug fixer for HARP (per M. Turmon)
1052             	// When AR is below threshold, "LONDTMIN", "LONDTMAX" will be wrong
1053             	// Also keywords such as "SIZE" will be NaN
1054             	// We compute minlon & minlat then by
1055             	// LONDTMIN(t) = LONDTMIN(t0) + (t - t0) * OMEGA_DT
1056             	
1057 xudong 1.15     //	float psize = drms_getkey_float(inRec, "SIZE", &status);
1058                 //	if (psize != psize) {
1059                 
1060                 if (minlon != minlon || maxlon != maxlon) {		// check lons instead of SIZE
1061 xudong 1.12 		TIME t0 = drms_getkey_time(inRec, "T_FRST1", &status); if (status) return 1;			// changed from T_FRST to T_FRST1, T_FRST may not exist
1062 xudong 1.1  		double omega = drms_getkey_double(inRec, "OMEGA_DT", &status); if (status) return 1;
1063             		char firstRecQuery[100], t0_str[100];
1064             		sprint_time(t0_str, t0, "TAI", 0);
1065             		snprintf(firstRecQuery, 100, "%s[%d][%s]", inRec->seriesinfo->seriesname, harpnum, t0_str);
1066             		DRMS_RecordSet_t *tmpRS = drms_open_records(drms_env, firstRecQuery, &status);
1067             		if (status || tmpRS->n != 1) return 1;
1068             		DRMS_Record_t *tmpRec = tmpRS->records[0];
1069             		double minlon0 = drms_getkey_double(tmpRec, "LONDTMIN", &status); if (status) return 1;
1070             		double maxlon0 = drms_getkey_double(tmpRec, "LONDTMAX", &status); if (status) return 1;
1071             		minlon = minlon0 + (trec - t0) * omega / SECINDAY;
1072             		maxlon = maxlon0 + (trec - t0) * omega / SECINDAY;
1073             		printf("%s, %f, %f\n", firstRecQuery, minlon, maxlon);
1074             	}
1075             	
1076             	mInfo->xc = (maxlon + minlon) / 2. + disk_lonc;
1077             	mInfo->yc = (maxlat + minlat) / 2.;
1078             	
1079             	/* Size */
1080             	
1081             	mInfo->ncol = round((maxlon - minlon) / mInfo->xscale);
1082             	mInfo->nrow = round((maxlat - minlat) / mInfo->yscale);
1083 xudong 1.1  	
1084             	return 0;
1085             	
1086             }
1087             
1088             
1089             /*
1090              * Fetch ephemeris info from a DRMS record
1091              * No error checking for now
1092              *
1093              */
1094             
1095             int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem)
1096             {
1097             	
1098             	int status = 0;
1099             	
1100             	float crota2 = drms_getkey_float(inRec, "CROTA2", &status);	// rotation
1101 xudong 1.15 	double sina = sin(crota2 * RADSINDEG);
1102 xudong 1.1  	double cosa = cos(crota2 * RADSINDEG);
1103             	
1104             	ephem->pa = - crota2 * RADSINDEG;
1105             	ephem->disk_latc = drms_getkey_float(inRec, "CRLT_OBS", &status) * RADSINDEG;
1106             	ephem->disk_lonc = drms_getkey_float(inRec, "CRLN_OBS", &status) * RADSINDEG;
1107             	
1108             	float crvalx = 0.0;
1109             	float crvaly = 0.0;
1110             	float crpix1 = drms_getkey_float(inRec, "IMCRPIX1", &status);
1111             	float crpix2 = drms_getkey_float(inRec, "IMCRPIX2", &status);
1112             	float cdelt = drms_getkey_float(inRec, "CDELT1", &status);  // in arcsec, assumimg dx=dy
1113             	ephem->disk_xc = PIX_X(0.0,0.0) - 1.0;		// Center of disk in pixel, starting at 0
1114             	ephem->disk_yc = PIX_Y(0.0,0.0) - 1.0;
1115             	
1116             	float dSun = drms_getkey_float(inRec, "DSUN_OBS", &status);
1117             	float rSun_ref = drms_getkey_float(inRec, "RSUN_REF", &status);
1118             	if (status) rSun_ref = 6.96e8;
1119             	
1120             	ephem->asd = asin(rSun_ref/dSun);
1121             	ephem->rSun = asin(rSun_ref / dSun) * RAD2ARCSEC / cdelt;
1122             	
1123 xudong 1.1  	return 0;
1124             	
1125             }
1126             
1127             
1128             /*
1129              * Compute the coordinates to be sampled on full disk image
1130              * mInfo->xi_out & mInfo->zeta_out
1131              * This is oversampled, its size is ncol0 & nrow0 as shown below
1132              *
1133              *
1134              */
1135             
1136             void findCoord(struct mapInfo *mInfo)
1137             {
1138             	
1139             	int ncol0 = mInfo->ncol * mInfo->nbin + (mInfo->nbin / 2) * 2;	// pad with nbin/2 on edge to avoid NAN
1140             	int nrow0 = mInfo->nrow * mInfo->nbin + (mInfo->nbin / 2) * 2;
1141             	
1142             	float xscale0 = mInfo->xscale / mInfo->nbin * RADSINDEG;		// oversampling resolution
1143             	float yscale0 = mInfo->yscale / mInfo->nbin * RADSINDEG;		// in rad
1144 xudong 1.1  	
1145             	double lonc = mInfo->xc * RADSINDEG;	// in rad
1146             	double latc = mInfo->yc * RADSINDEG;
1147             	
1148             	double disk_lonc = (mInfo->ephem).disk_lonc;
1149             	double disk_latc = (mInfo->ephem).disk_latc;
1150             	
1151             	double rSun = (mInfo->ephem).rSun;
1152             	double disk_xc = (mInfo->ephem).disk_xc / rSun;
1153             	double disk_yc = (mInfo->ephem).disk_yc / rSun;
1154             	double pa = (mInfo->ephem).pa;
1155             	
1156             	// Temp pointers
1157             	
1158             	float *xi_out = mInfo->xi_out;
1159             	float *zeta_out = mInfo->zeta_out;
1160             	
1161             	// start
1162             	
1163             	double x, y;		// map coord
1164             	double lat, lon;	// helio coord
1165 xudong 1.1  	double xi, zeta;	// image coord (for one point)
1166             	
1167             	int ind_map;
1168             	
1169             	for (int row0 = 0; row0 < nrow0; row0++) {
1170             		for (int col0 = 0; col0 < ncol0; col0++) {
1171             			
1172             			ind_map = row0 * ncol0 + col0;
1173             			
1174             			x = (col0 + 0.5 - ncol0/2.) * xscale0;		// in rad
1175             			y = (row0 + 0.5 - nrow0/2.) * yscale0;
1176             			
1177 xudong 1.15 			/* map grid [x, y] corresponds to the point [lon, lat] in the heliographic coordinates.
1178 xudong 1.1  			 * the [x, y] are in radians with respect of the center of the map [xcMap, ycMap].
1179             			 * projection methods could be Mercator, Lambert, and many others. [maplonc, mapLatc]
1180 xudong 1.15 			 * is the heliographic longitude and latitude of the map center. Both are in degree.
1181 xudong 1.1  			 */
1182             			
1183             			if (plane2sphere (x, y, latc, lonc, &lat, &lon, (int) mInfo->proj)) {
1184             				xi_out[ind_map] = -1;
1185             				zeta_out[ind_map] = -1;
1186             				continue;
1187             			}
1188             			
1189             			/* map the grid [lon, lat] in the heliographic coordinates to [xi, zeta], a point in the
1190             			 * image coordinates. The image properties, xCenter, yCenter, rSun, pa, ecc and chi are given.
1191             			 */
1192             			
1193 xudong 1.15 			if (sphere2img (lat, lon, disk_latc, disk_lonc, &xi, &zeta,
1194 xudong 1.1  							disk_xc, disk_yc, 1.0, pa, 0., 0., 0., 0.)) {
1195             				xi_out[ind_map] = -1;
1196             				zeta_out[ind_map] = -1;
1197             				continue;
1198             			}
1199             			
1200             			xi_out[ind_map] = xi * rSun;
1201             			zeta_out[ind_map] = zeta * rSun;
1202             			
1203             		}
1204             	}
1205             	
1206             }
1207             
1208             
1209 xudong 1.15 /*
1210 xudong 1.1   * Sampling function
1211              * oversampling by nbin, then binning using a Gaussian
1212              * save results in outData, always of float type
1213              *
1214              */
1215             
1216 xudong 1.17 int performSampling(float *outData, float *inData, struct mapInfo *mInfo, int interpOpt)
1217 xudong 1.1  {
1218             	
1219             	int status = 0;
1220 xudong 1.17 	int ind_map;
1221 xudong 1.1  	
1222             	int ncol0 = mInfo->ncol * mInfo->nbin + (mInfo->nbin / 2) * 2;	// pad with nbin/2 on edge to avoid NAN
1223             	int nrow0 = mInfo->nrow * mInfo->nbin + (mInfo->nbin / 2) * 2;
1224             	
1225 xudong 1.17 	// Changed Aug 12 2013, XS, for bitmaps
1226             	float *outData0;
1227             	if (interpOpt == 3 && mInfo->nbin == 1) {
1228 xudong 1.23         outData0 = outData;
1229 xudong 1.17 	} else {
1230 xudong 1.23         outData0 = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
1231 xudong 1.17 	}
1232 xudong 1.1  	
1233             	float *xi_out = mInfo->xi_out;
1234             	float *zeta_out = mInfo->zeta_out;
1235 xudong 1.6  	
1236 xudong 1.1  	// Interpolation
1237             	
1238             	struct fint_struct pars;
1239 xudong 1.17 	// Aug 12 2013, passed in as argument now
1240 xudong 1.1  	
1241             	switch (interpOpt) {
1242             		case 0:			// Wiener, 6 order, 1 constraint
1243             			init_finterpolate_wiener(&pars, 6, 1, 6, 2, 1, 1, NULL, dpath);
1244             			break;
1245             		case 1:			// Cubic convolution
1246             			init_finterpolate_cubic_conv(&pars, 1., 3.);
1247             			break;
1248             		case 2:			// Bilinear
1249             			init_finterpolate_linear(&pars, 1.);
1250             			break;
1251 xudong 1.17 		case 3:			// Near neighbor
1252 xudong 1.23             break;
1253 xudong 1.1  		default:
1254             			return 1;
1255             	}
1256             	
1257 xudong 1.17 	printf("interpOpt = %d, nbin = %d ", interpOpt, mInfo->nbin);
1258             	if (interpOpt == 3) {			// Aug 6 2013, Xudong
1259             	  	for (int row0 = 0; row0 < nrow0; row0++) {
1260 xudong 1.23             for (int col0 = 0; col0 < ncol0; col0++) {
1261                             ind_map = row0 * ncol0 + col0;
1262                             outData0[ind_map] = nnb(inData, FOURK, FOURK, xi_out[ind_map], zeta_out[ind_map]);
1263                         }
1264                     }
1265 xudong 1.17 	} else {
1266 xudong 1.23         finterpolate(&pars, inData, xi_out, zeta_out, outData0,
1267                                  FOURK, FOURK, FOURK, ncol0, nrow0, ncol0, DRMS_MISSING_FLOAT);
1268 xudong 1.17 	}
1269 xudong 1.1  	
1270             	// Rebinning, smoothing
1271             	
1272 xudong 1.17 	if (interpOpt == 3 && mInfo->nbin == 1) {
1273 xudong 1.23         return 0;
1274 xudong 1.17 	} else {
1275 xudong 1.23         frebin(outData0, outData, ncol0, nrow0, mInfo->nbin, 1);		// Gaussian
1276                     free(outData0);		// Dec 18 2012
1277 xudong 1.17 	}
1278 xudong 1.1  	
1279             	//
1280             	
1281             	return 0;
1282             	
1283             }
1284             
1285             
1286 xudong 1.15 /*
1287 xudong 1.1   * Performing local vector transformation
1288              *  xyz: z refers to vertical (radial) component, x EW (phi), y NS
1289              *
1290              */
1291             
1292             void vectorTransform(float *bx_map, float *by_map, float *bz_map, struct mapInfo *mInfo)
1293             {
1294             	
1295             	int ncol = mInfo->ncol;
1296             	int nrow = mInfo->nrow;
1297             	
1298             	float xscale = mInfo->xscale * RADSINDEG;		// in rad
1299             	float yscale = mInfo->yscale * RADSINDEG;
1300             	
1301             	double lonc = mInfo->xc * RADSINDEG;	// in rad
1302             	double latc = mInfo->yc * RADSINDEG;
1303             	
1304             	double disk_lonc = (mInfo->ephem).disk_lonc;
1305             	double disk_latc = (mInfo->ephem).disk_latc;
1306             	
1307             	double rSun = (mInfo->ephem).rSun;
1308 xudong 1.1  	double disk_xc = (mInfo->ephem).disk_xc / rSun;
1309             	double disk_yc = (mInfo->ephem).disk_yc / rSun;
1310             	double pa = (mInfo->ephem).pa;
1311             	
1312             	int ind_map;
1313             	double x, y;
1314             	double lat, lon;	// lat / lon for current point
1315             	
1316             	double bx_tmp, by_tmp, bz_tmp;
1317             	
1318             	//
1319             	
1320             	for (int row = 0; row < mInfo->nrow; row++) {
1321             		for (int col = 0; col < mInfo->ncol; col++) {
1322             			
1323             			ind_map = row * mInfo->ncol + col;
1324             			
1325             			x = (col + 0.5 - ncol / 2.) * xscale;
1326             			y = (row + 0.5 - nrow / 2.) * yscale;
1327             			
1328             			if (plane2sphere (x, y, latc, lonc, &lat, &lon, (int) mInfo->proj)) {
1329 xudong 1.1  				bx_map[ind_map] = DRMS_MISSING_FLOAT;
1330             				by_map[ind_map] = DRMS_MISSING_FLOAT;
1331             				bz_map[ind_map] = DRMS_MISSING_FLOAT;
1332             				continue;
1333             			}
1334             			
1335             			bx_tmp = by_tmp = bz_tmp = 0;
1336             			
1337             			img2helioVector (bx_map[ind_map], by_map[ind_map], bz_map[ind_map],
1338             							 &bx_tmp, &by_tmp, &bz_tmp,
1339             							 lon, lat, disk_lonc, disk_latc, pa);
1340             			
1341             			bx_map[ind_map] = bx_tmp;
1342             			by_map[ind_map] = by_tmp;
1343             			bz_map[ind_map] = bz_tmp;
1344             			
1345             		}
1346             	}
1347 xudong 1.6  	
1348 xudong 1.1  }
1349             
1350             
1351             
1352 xudong 1.15 /*
1353 xudong 1.1   * Map and propogate vector field errors
1354              *
1355              */
1356             
1357             int getBErr(float *bx_err, float *by_err, float *bz_err,
1358 xudong 1.6  			DRMS_Record_t *inRec, struct mapInfo *mInfo)
1359 xudong 1.1  {
1360             	
1361             	int status = 0;
1362             	
1363             	// Get variances and covariances, filling factor assume to be 1
1364             	
1365             	float *bT = (float *) (malloc(FOURK2 * sizeof(float)));	// field
1366             	float *bI = (float *) (malloc(FOURK2 * sizeof(float)));	// inclination
1367             	float *bA = (float *) (malloc(FOURK2 * sizeof(float)));	// azimuth
1368             	
1369             	float *errbT = (float *) (malloc(FOURK2 * sizeof(float)));
1370             	float *errbI = (float *) (malloc(FOURK2 * sizeof(float)));
1371             	float *errbA = (float *) (malloc(FOURK2 * sizeof(float)));
1372             	
1373             	float *errbTbI = (float *) (malloc(FOURK2 * sizeof(float)));
1374             	float *errbTbA = (float *) (malloc(FOURK2 * sizeof(float)));
1375             	float *errbIbA = (float *) (malloc(FOURK2 * sizeof(float)));
1376             	
1377 xudong 1.15 	if (readVectorBErr(inRec,
1378 xudong 1.1  					   bT, bI, bA,
1379 xudong 1.15 					   errbT, errbI, errbA,
1380 xudong 1.1  					   errbTbI, errbTbA, errbIbA)) {
1381             		printf("Read full disk variances & covariances error\n");
1382             		free(bT); free(bI); free(bA);
1383             		free(errbT); free(errbI); free(errbA);
1384             		free(errbTbI); free(errbTbA); free(errbIbA);
1385             		return 1;
1386             	}
1387             	
1388             	// Size
1389             	
1390             	int ncol = mInfo->ncol;
1391             	int nrow = mInfo->nrow;
1392             	
1393             	float xscale = mInfo->xscale * RADSINDEG;		// in rad
1394             	float yscale = mInfo->yscale * RADSINDEG;
1395             	
1396             	double lonc = mInfo->xc * RADSINDEG;	// in rad
1397             	double latc = mInfo->yc * RADSINDEG;
1398             	
1399             	double disk_lonc = (mInfo->ephem).disk_lonc;
1400             	double disk_latc = (mInfo->ephem).disk_latc;
1401 xudong 1.1  	
1402             	double rSun = (mInfo->ephem).rSun;
1403             	double disk_xc = (mInfo->ephem).disk_xc / rSun;
1404             	double disk_yc = (mInfo->ephem).disk_yc / rSun;
1405             	double pa = (mInfo->ephem).pa;
1406             	
1407             	// Start
1408             	
1409             	double x, y;          // map coord
1410             	double lat, lon;      // spherical coord
1411             	double xi, zeta;      // image coord, round to full pixel
1412             	
1413             	int ind_map, ind_img;
1414             	
1415             	double bpSigma2, btSigma2, brSigma2;		// variances after prop
1416 xudong 1.6  	
1417 xudong 1.1  	for (int row = 0; row < mInfo->nrow; row++) {
1418             		for (int col = 0; col < mInfo->ncol; col++) {
1419             			
1420             			ind_map = row * mInfo->ncol + col;
1421             			
1422             			x = (col + 0.5 - ncol / 2.) * xscale;
1423             			y = (row + 0.5 - nrow / 2.) * yscale;
1424             			
1425             			if (plane2sphere (x, y, latc, lonc, &lat, &lon, (int) mInfo->proj)) {
1426             				bx_err[ind_map] = DRMS_MISSING_FLOAT;
1427             				by_err[ind_map] = DRMS_MISSING_FLOAT;
1428             				bz_err[ind_map] = DRMS_MISSING_FLOAT;
1429             				continue;
1430             			}
1431             			
1432 xudong 1.15 			if (sphere2img (lat, lon, disk_latc, disk_lonc, &xi, &zeta,
1433 xudong 1.1  							disk_xc, disk_yc, 1.0, pa, 0., 0., 0., 0.)) {
1434             				bx_err[ind_map] = DRMS_MISSING_FLOAT;
1435 xudong 1.24 				by_err[ind_map] = DRMS_MISSING_FLOAT;
1436             				bz_err[ind_map] = DRMS_MISSING_FLOAT;       // Mar 7
1437 xudong 1.1  				continue;
1438             			}
1439             			
1440             			xi *= rSun; xi = round(xi);
1441             			zeta *= rSun; zeta = round(zeta);     // nearest neighbor
1442             			
1443             			ind_img = round(zeta * FOURK + xi);
1444             			
1445 xudong 1.15 			if (errorprop(bT, bA, bI,
1446             						  errbT, errbA, errbI, errbTbA, errbTbI, errbIbA,
1447             						  lon, lat, disk_lonc, disk_latc, pa, FOURK, FOURK, xi, zeta,
1448 xudong 1.1  						  &btSigma2, &bpSigma2, &brSigma2)) {
1449             				bx_err[ind_map] = DRMS_MISSING_FLOAT;
1450             				by_err[ind_map] = DRMS_MISSING_FLOAT;
1451             				bz_err[ind_map] = DRMS_MISSING_FLOAT;
1452             				continue;
1453             			}
1454             			
1455             			bx_err[ind_map] = sqrt(bpSigma2);
1456             			by_err[ind_map] = sqrt(btSigma2);
1457             			bz_err[ind_map] = sqrt(brSigma2);
1458             			
1459             		}
1460             	}
1461             	
1462             	//
1463             	
1464             	free(bT); free(bI); free(bA);
1465             	free(errbT); free(errbI); free(errbA);
1466             	free(errbTbI); free(errbTbA); free(errbIbA);
1467             	return 0;
1468             	
1469 xudong 1.1  }
1470             
1471             
1472             
1473             /*
1474              * Read full disk vector magnetograms
1475              * Fill factor is 1, use default disambiguity resolution
1476              *
1477              */
1478             
1479             int readVectorB(DRMS_Record_t *inRec, float *bx_img, float *by_img, float *bz_img)
1480             {
1481             	
1482             	int status = 0;
1483             	
1484             	DRMS_Segment_t *inSeg;
1485             	DRMS_Array_t *inArray_ambig;
1486 xudong 1.6  	DRMS_Array_t *inArray_bTotal, *inArray_bAzim, *inArray_bIncl;
1487 xudong 1.1  	
1488             	char *ambig;
1489             	float *bTotal, *bAzim, *bIncl;
1490             	
1491             	inSeg = drms_segment_lookup(inRec, "disambig");
1492             	inArray_ambig = drms_segment_read(inSeg, DRMS_TYPE_CHAR, &status);
1493             	if (status) return 1;
1494             	ambig = (char *)inArray_ambig->data;
1495             	
1496             	inSeg = drms_segment_lookup(inRec, "field");
1497             	inArray_bTotal = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
1498             	if (status) return 1;
1499             	bTotal = (float *)inArray_bTotal->data;
1500             	
1501             	inSeg = drms_segment_lookup(inRec, "azimuth");
1502             	inArray_bAzim = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
1503             	if (status) return 1;
1504             	bAzim = (float *)inArray_bAzim->data;
1505             	
1506             	inSeg = drms_segment_lookup(inRec, "inclination");
1507             	inArray_bIncl = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
1508 xudong 1.1  	if (status) return 1;
1509             	bIncl = (float *)inArray_bIncl->data;
1510             	
1511             	// Convert CCD xyz
1512             	
1513             	int llx, lly;		// lower-left corner
1514             	int bmx, bmy;		// bitmap size
1515 xudong 1.23     
1516                 if (fullDisk) {
1517                     llx = lly = 0;
1518                     bmx = bmy = FOURK;
1519                 } else {
1520                     llx = (int)(drms_getkey_float(inRec, "CRPIX1", &status)) - 1;
1521                     lly = (int)(drms_getkey_float(inRec, "CRPIX2", &status)) - 1;
1522                     bmx = inArray_ambig->axis[0];
1523                     bmy = inArray_ambig->axis[1];
1524                 }
1525 xudong 1.1  	
1526             	int kx, ky, kOff;
1527             	int ix = 0, jy = 0, yOff = 0, iData = 0;
1528             	int xDim = FOURK, yDim = FOURK;
1529 xudong 1.23 	int amb = 0;
1530 xudong 1.1  	
1531             	for (jy = 0; jy < yDim; jy++)
1532             	{
1533             		ix = 0;
1534             		yOff = jy * xDim;
1535             		ky = jy - lly;
1536             		for (ix = 0; ix < xDim; ix++)
1537             		{
1538             			iData = yOff + ix;
1539             			kx = ix - llx;
1540             			
1541             			// zero azi pointing up, zero incl pointing out from sun
1542             			bx_img[iData] = - bTotal[iData] * sin(bIncl[iData] * RADSINDEG) * sin(bAzim[iData] * RADSINDEG);
1543             			by_img[iData] = bTotal[iData] * sin(bIncl[iData] * RADSINDEG) * cos(bAzim[iData] * RADSINDEG);
1544             			bz_img[iData] = bTotal[iData] * cos(bIncl[iData] * RADSINDEG);
1545                         
1546             			// Disambiguation
1547             			
1548             			if (kx < 0 || kx >= bmx || ky < 0 || ky >= bmy) {
1549             				continue;
1550             			} else {
1551 xudong 1.1  				kOff = ky * bmx + kx;
1552 xudong 1.23                 //				if (ambig[kOff] % 2) {		// 180
1553             				// Feb 12 2014, use bit #2 for full disk, lowest bit for patch
1554             				if (fullDisk) { amb = (ambig[kOff] / 4) % 2; } else { amb = ambig[kOff] % 2; }
1555             				if (amb) {				// Feb 12 2014, use bit #2
1556 xudong 1.1  					bx_img[iData] *= -1.; by_img[iData] *= -1.;
1557 xudong 1.15 				}
1558 xudong 1.1  			}
1559             		}
1560             	}
1561             	
1562             	// Clean up
1563             	
1564             	drms_free_array(inArray_ambig);
1565             	drms_free_array(inArray_bTotal);
1566             	drms_free_array(inArray_bAzim);
1567             	drms_free_array(inArray_bIncl);
1568             	
1569             	return 0;
1570             	
1571             }
1572             
1573             
1574             /*
1575              * Read variances and covariances of vector magnetograms
1576              *
1577              */
1578             
1579 xudong 1.15 int readVectorBErr(DRMS_Record_t *inRec,
1580 xudong 1.1  				   float *bT, float *bI, float *bA,
1581 xudong 1.15 				   float *errbT, float *errbI, float *errbA,
1582 xudong 1.1  				   float *errbTbI, float *errbTbA, float *errbIbA)
1583             {
1584             	
1585             	int status = 0;
1586             	
1587             	float *data_ptr[9];
1588             	char *segName[9] = {"field", "inclination", "azimuth",
1589 xudong 1.6  		"field_err", "inclination_err", "azimuth_err",
1590             		"field_inclination_err", "field_az_err", "inclin_azimuth_err"};
1591 xudong 1.1  	DRMS_Segment_t *inSegs[9];
1592             	DRMS_Array_t *inArrays[9];
1593             	
1594             	// Read full disk images
1595 xudong 1.23     // Do we need disambig? Dec 30 XS
1596 xudong 1.1  	
1597             	for (int iSeg = 0; iSeg < 9; iSeg++) {
1598             		
1599             		inSegs[iSeg] = drms_segment_lookup(inRec, segName[iSeg]);
1600             		inArrays[iSeg] = drms_segment_read(inSegs[iSeg], DRMS_TYPE_FLOAT, &status);
1601             		data_ptr[iSeg] = (float *) inArrays[iSeg]->data;
1602             		
1603             	}
1604             	
1605             	float *bT0 = data_ptr[0], *bI0 = data_ptr[1], *bA0 = data_ptr[2];
1606             	float *errbT0 = data_ptr[3], *errbI0 = data_ptr[4], *errbA0 = data_ptr[5];
1607             	float *errbTbI0 = data_ptr[6], *errbTbA0 = data_ptr[7], *errbIbA0 = data_ptr[8];
1608             	
1609 xudong 1.23 	// Add disambig, Feb 12 2014
1610             	
1611             	DRMS_Segment_t *inSeg;
1612                 DRMS_Array_t *inArray_ambig;
1613                 
1614                 if (amb4err) {              // Mar 4 2014
1615                 
1616                     inSeg = drms_segment_lookup(inRec, "disambig");
1617                     inArray_ambig = drms_segment_read(inSeg, DRMS_TYPE_CHAR, &status);
1618                     if (status) return 1;
1619                     char *ambig = (char *)inArray_ambig->data;
1620                     
1621                     int llx, lly;		// lower-left corner
1622                     int bmx, bmy;		// bitmap size
1623                     
1624                     if (fullDisk) {
1625                         llx = lly = 0;
1626                         bmx = bmy = FOURK;
1627                     } else {
1628                         llx = (int)(drms_getkey_float(inRec, "CRPIX1", &status)) - 1;
1629                         lly = (int)(drms_getkey_float(inRec, "CRPIX2", &status)) - 1;
1630 xudong 1.23             bmx = inArray_ambig->axis[0];
1631                         bmy = inArray_ambig->axis[1];
1632                     }
1633                     
1634                     int idx, idx_a;
1635                     int amb;
1636                     
1637                     for (int j = 0; j < bmy; j++) {
1638                         for (int i = 0; i < bmx; i++) {
1639                             idx_a = j * bmx + i;
1640                             idx = (j + lly) * FOURK + (i + llx);
1641                             // Feb 12 2014, use bit #2 for full disk, lowest bit for patch
1642                             if (fullDisk) { amb = (ambig[idx_a] / 4) % 2; } else { amb = ambig[idx_a] % 2; }
1643                             if (amb) { bA0[idx] += 180.; }
1644                         }
1645                     }
1646                     
1647                 }
1648                 
1649 xudong 1.1  	// Convert errors to variances, correlation coefficients to covariances
1650             	
1651             	for (int i = 0; i < FOURK2; i++) {
1652             		
1653             		if (fabs(errbI0[i]) > 180.) errbI0[i] = 180.;
1654             		if (fabs(errbA0[i]) > 180.) errbA0[i] = 180.;
1655             		
1656             		bT[i] = bT0[i];
1657 xudong 1.23 		bI[i] = bI0[i];		// in deg, coverted in errorprop
1658 xudong 1.1  		bA[i] = bA0[i];
1659             		
1660             		errbT[i] = errbT0[i] * errbT0[i];
1661             		errbI[i] = errbI0[i] * errbI0[i] * RADSINDEG * RADSINDEG;
1662             		errbA[i] = errbA0[i] * errbA0[i] * RADSINDEG * RADSINDEG;
1663             		
1664             		errbTbI[i] = errbTbI0[i] * errbT0[i] * errbI0[i] * RADSINDEG;
1665                     errbTbA[i] = errbTbA0[i] * errbT0[i] * errbA0[i] * RADSINDEG;
1666                     errbIbA[i] = errbIbA0[i] * errbI0[i] * errbA0[i] * RADSINDEG * RADSINDEG;
1667 xudong 1.6  		
1668 xudong 1.1  	}
1669             	
1670             	//
1671             	
1672             	for (int iSeg = 0; iSeg < 9; iSeg++) drms_free_array(inArrays[iSeg]);
1673 xudong 1.23 	if (amb4err) drms_free_array(inArray_ambig);		// Feb 12; Mar 04 2014
1674 xudong 1.6  	
1675 xudong 1.1  	return 0;
1676             	
1677             }
1678             
1679             
1680             /*
1681              * Create Cutout record: top level subroutine
1682              * Do the loops on segments and set the keywords here
1683              * Work is done in writeCutout routine below
1684 xudong 1.15  *
1685 xudong 1.1   */
1686             
1687 xudong 1.15 int createCutRecord(DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec,
1688             					DRMS_Record_t *dopRec, DRMS_Record_t *contRec,
1689 xudong 1.1  					DRMS_Record_t *sharpRec, struct swIndex *swKeys_ptr)
1690             {
1691             	
1692             	int status = 0;
1693             	
1694             	int iHarpSeg;
1695             	int nMharpSegs = ARRLENGTH(MharpSegs), nBharpSegs = ARRLENGTH(BharpSegs);
1696             	
1697             	// Cutout Mharp
1698             	
1699             	for (iHarpSeg = 0; iHarpSeg < nMharpSegs; iHarpSeg++) {
1700             		if (writeCutout(sharpRec, mharpRec, mharpRec, MharpSegs[iHarpSeg])) {
1701             			printf("Mharp cutout fails for %s\n", MharpSegs[iHarpSeg]);
1702             			break;
1703             		}
1704             	}
1705 xudong 1.3  	if (iHarpSeg != nMharpSegs) {
1706             		SHOW("Cutout: segment number unmatch\n");
1707             		return 1;		// if failed
1708             	}
1709 xudong 1.1  	printf("Magnetogram cutout done.\n");
1710             	
1711             	// Cutout Doppler
1712             	
1713             	if (writeCutout(sharpRec, dopRec, mharpRec, "Dopplergram")) {
1714             		printf("Doppler cutout failed\n");
1715             		return 1;
1716             	}
1717             	printf("Dopplergram cutout done.\n");
1718             	
1719             	// Cutout Continuum
1720             	
1721             	if (writeCutout(sharpRec, contRec, mharpRec, "continuum")) {
1722             		printf("Continuum cutout failed\n");
1723             		return 1;
1724             	}
1725             	printf("Intensitygram cutout done.\n");
1726             	
1727             	// Coutout Bharp
1728             	
1729             	for (iHarpSeg = 0; iHarpSeg < nBharpSegs; iHarpSeg++) {
1730 xudong 1.1  		if (writeCutout(sharpRec, bharpRec, mharpRec, BharpSegs[iHarpSeg])) {
1731             			printf("Bharp cutout fails for %s\n", BharpSegs[iHarpSeg]);
1732             			break;
1733             		}
1734             	}
1735             	if (iHarpSeg != nBharpSegs) return 1;		// if failed
1736             	printf("Vector B cutout done.\n");
1737             	
1738             	// Keywords & Links
1739             	
1740             	drms_copykey(sharpRec, mharpRec, "T_REC");
1741             	drms_copykey(sharpRec, mharpRec, "HARPNUM");
1742             	
1743             	DRMS_Link_t *mHarpLink = hcon_lookup_lower(&sharpRec->links, "MHARP");
1744             	if (mHarpLink) drms_link_set("MHARP", sharpRec, mharpRec);
1745             	DRMS_Link_t *bHarpLink = hcon_lookup_lower(&sharpRec->links, "BHARP");
1746             	if (bHarpLink) drms_link_set("BHARP", sharpRec, bharpRec);
1747             	
1748             	setSWIndex(sharpRec, swKeys_ptr);	// Set space weather indices
1749 xudong 1.23 	setKeys(sharpRec, mharpRec, bharpRec, NULL);              // Set all other keywords, NULL specifies cutout
1750 xudong 1.6  	
1751 xudong 1.1  	// Stats
1752 xudong 1.6  	
1753 xudong 1.1  	int nCutSegs = ARRLENGTH(CutSegs);
1754             	for (int iSeg = 0; iSeg < nCutSegs; iSeg++) {
1755             		DRMS_Segment_t *outSeg = drms_segment_lookupnum(sharpRec, iSeg);
1756             		DRMS_Array_t *outArray = drms_segment_read(outSeg, DRMS_TYPE_FLOAT, &status);
1757             		set_statistics(outSeg, outArray, 1);
1758             		drms_free_array(outArray);
1759             	}
1760 xudong 1.6  	
1761 xudong 1.1  	return 0;
1762             	
1763 xudong 1.15 }
1764 xudong 1.1  
1765             
1766 xudong 1.15 /*
1767 xudong 1.1   * Get cutout and write segment
1768              * Change DISAMB_AZI to apply disambiguation to azimuth
1769              *
1770              */
1771             
1772             int writeCutout(DRMS_Record_t *outRec, DRMS_Record_t *inRec, DRMS_Record_t *harpRec, char *SegName)
1773             {
1774             	
1775             	int status = 0;
1776             	
1777             	DRMS_Segment_t *inSeg = NULL, *outSeg = NULL;
1778             	DRMS_Array_t *cutoutArray = NULL;
1779             	//	DRMS_Type_t arrayType;
1780             	
1781             	int ll[2], ur[2], nx, ny, nxny;		// lower-left and upper right coords
1782             	
1783             	/* Info */
1784             	
1785             	inSeg = drms_segment_lookup(inRec, SegName);
1786             	if (!inSeg) return 1;
1787             	
1788 xudong 1.1  	nx = (int) drms_getkey_float(harpRec, "CRSIZE1", &status);
1789             	ny = (int) drms_getkey_float(harpRec, "CRSIZE2", &status);
1790             	nxny = nx * ny;
1791             	ll[0] = (int) drms_getkey_float(harpRec, "CRPIX1", &status) - 1; if (status) return 1;
1792             	ll[1] = (int) drms_getkey_float(harpRec, "CRPIX2", &status) - 1; if (status) return 1;
1793             	ur[0] = ll[0] + nx - 1; if (status) return 1;
1794             	ur[1] = ll[1] + ny - 1; if (status) return 1;
1795             	
1796             	if (inSeg->axis[0] == nx && inSeg->axis[1] == ny) {			// for bitmaps, infomaps, etc.
1797             		cutoutArray = drms_segment_read(inSeg, DRMS_TYPE_DOUBLE, &status);
1798             		if (status) return 1;
1799             	} else if (inSeg->axis[0] == FOURK && inSeg->axis[1] == FOURK) {		// for full disk ones
1800             		cutoutArray = drms_segment_readslice(inSeg, DRMS_TYPE_DOUBLE, ll, ur, &status);
1801             		if (status) return 1;
1802             	} else {
1803             		return 1;
1804             	}
1805 xudong 1.6  	
1806 xudong 1.23 	// Feb 12 2014, fool-proof, for patch, change everything to 0 or 7!!!
1807             	// This is a fix for disambiguation before Aug 2013
1808             	
1809             	if (!strcmp(SegName, "disambig") && !fullDisk) {
1810             		double *disamb = (double *) (cutoutArray->data);
1811             		for (int i = 0; i < nxny; i++) {
1812             			if (((int)disamb[i]) % 2) { disamb[i] = 7; } else { disamb[i] = 0; }
1813             		}
1814             	}
1815             	
1816 xudong 1.1  	/* Adding disambiguation resolution to cutout azimuth? */
1817 xudong 1.6  	
1818 xudong 1.1  #if DISAMB_AZI
1819 xudong 1.23 	int amb;
1820 xudong 1.1  	if (!strcmp(SegName, "azimuth")) {
1821 xudong 1.6  		DRMS_Segment_t *disambSeg = NULL;
1822             		disambSeg = drms_segment_lookup(inRec, "disambig");
1823 xudong 1.1  		if (!disambSeg) {drms_free_array(cutoutArray); return 1;}
1824             		DRMS_Array_t *disambArray;
1825 xudong 1.23         if (fullDisk) { // Jan 2 2014 XS
1826                         disambArray = drms_segment_readslice(disambSeg, DRMS_TYPE_CHAR, ll, ur, &status);
1827                         if (status) return 1;
1828                     } else {
1829                         if (disambSeg->axis[0] == nx && disambSeg->axis[1] == ny) {
1830                             disambArray = drms_segment_read(disambSeg, DRMS_TYPE_CHAR, &status);
1831                             if (status) {drms_free_array(cutoutArray); return 1;}
1832                         } else {
1833                             drms_free_array(cutoutArray);
1834                             return 1;
1835                         }
1836                     }
1837 xudong 1.1  		double *azimuth = (double *) cutoutArray->data;
1838             		char *disamb = (char *) disambArray->data;
1839             		for (int n = 0; n < nxny; n++) {
1840 xudong 1.23             //			if (disamb[n] % 2) azimuth[n] += 180.;      // Nov 12 2013 Fixed!!!
1841             			// Feb 12 2014, use bit #2 for full disk, lowest bit for patch
1842             			if (fullDisk) { amb = (disamb[n] / 4) % 2; } else { amb = disamb[n] % 2; }
1843             			if (amb) azimuth[n] += 180.;
1844 xudong 1.1  		}
1845             		drms_free_array(disambArray);
1846             	}
1847             #endif
1848 xudong 1.6  	
1849 xudong 1.1  	/* Write out */
1850             	
1851             	outSeg = drms_segment_lookup(outRec, SegName);
1852             	if (!outSeg) return 1;
1853 xudong 1.15     //	drms_array_convert_inplace(outSeg->info->type, 0, 1, cutoutArray);	// Jan 02 2013
1854 xudong 1.1  	outSeg->axis[0] = cutoutArray->axis[0];
1855             	outSeg->axis[1] = cutoutArray->axis[1];
1856 xudong 1.15     //	cutoutArray->parent_segment = outSeg;
1857 xudong 1.8  	cutoutArray->israw = 0;		// always compressed
1858 xudong 1.1      cutoutArray->bzero = outSeg->bzero;
1859                 cutoutArray->bscale = outSeg->bscale;		// Same as inArray's
1860             	status = drms_segment_write(outSeg, cutoutArray, 0);
1861             	drms_free_array(cutoutArray);
1862             	if (status) return 1;
1863             	
1864             	return 0;
1865             	
1866             }
1867             
1868             
1869 xudong 1.15 /*
1870 xudong 1.1   * Compute space weather indices, no error checking for now
1871              * Based on M. Bobra's swharp_vectorB.c
1872              * No error checking for now
1873              *
1874              */
1875             
1876             void computeSWIndex(struct swIndex *swKeys_ptr, DRMS_Record_t *inRec, struct mapInfo *mInfo)
1877             {
1878             	
1879             	int status = 0;
1880             	int nx = mInfo->ncol, ny = mInfo->nrow;
1881             	int nxny = nx * ny;
1882             	int dims[2] = {nx, ny};
1883 xudong 1.15     
1884 xudong 1.1  	// Get bx, by, bz, mask
1885             	
1886 xudong 1.6  	// Use HARP (Turmon) bitmap as a threshold on spaceweather quantities
1887 mbobra 1.5  	DRMS_Segment_t *bitmaskSeg = drms_segment_lookup(inRec, "bitmap");
1888             	DRMS_Array_t *bitmaskArray = drms_segment_read(bitmaskSeg, DRMS_TYPE_INT, &status);
1889             	int *bitmask = (int *) bitmaskArray->data;		// get the previously made mask array
1890 xudong 1.6  	
1891 xudong 1.15 	//Use conf_disambig map as a threshold on spaceweather quantities
1892             	DRMS_Segment_t *maskSeg = drms_segment_lookup(inRec, "conf_disambig");
1893 xudong 1.1  	DRMS_Array_t *maskArray = drms_segment_read(maskSeg, DRMS_TYPE_INT, &status);
1894             	int *mask = (int *) maskArray->data;		// get the previously made mask array
1895 xudong 1.6  	
1896 xudong 1.1  	DRMS_Segment_t *bxSeg = drms_segment_lookup(inRec, BP_SEG_CEA);
1897             	DRMS_Array_t *bxArray = drms_segment_read(bxSeg, DRMS_TYPE_FLOAT, &status);
1898             	float *bx = (float *) bxArray->data;		// bx
1899             	
1900             	DRMS_Segment_t *bySeg = drms_segment_lookup(inRec, BT_SEG_CEA);
1901             	DRMS_Array_t *byArray = drms_segment_read(bySeg, DRMS_TYPE_FLOAT, &status);
1902             	float *by = (float *) byArray->data;		// by
1903             	for (int i = 0; i < nxny; i++) by[i] *= -1;
1904             	
1905             	DRMS_Segment_t *bzSeg = drms_segment_lookup(inRec, BR_SEG_CEA);
1906             	DRMS_Array_t *bzArray = drms_segment_read(bzSeg, DRMS_TYPE_FLOAT, &status);
1907             	float *bz = (float *) bzArray->data;		// bz
1908 xudong 1.15     
1909 xudong 1.23     //Use magnetogram map to compute R
1910                 DRMS_Segment_t *losSeg = drms_segment_lookup(inRec, "magnetogram");
1911                 DRMS_Array_t *losArray = drms_segment_read(losSeg, DRMS_TYPE_FLOAT, &status);
1912                 float *los = (float *) losArray->data;          // los
1913                 
1914 mbobra 1.14 	DRMS_Segment_t *bz_errSeg = drms_segment_lookup(inRec, BR_ERR_SEG_CEA);
1915             	DRMS_Array_t *bz_errArray = drms_segment_read(bz_errSeg, DRMS_TYPE_FLOAT, &status);
1916             	float *bz_err = (float *) bz_errArray->data;		// bz_err
1917 xudong 1.15     
1918 mbobra 1.14 	DRMS_Segment_t *by_errSeg = drms_segment_lookup(inRec, BT_ERR_SEG_CEA);
1919             	DRMS_Array_t *by_errArray = drms_segment_read(by_errSeg, DRMS_TYPE_FLOAT, &status);
1920             	float *by_err = (float *) by_errArray->data;		// by_err
1921             	//for (int i = 0; i < nxny; i++) by_err[i] *= -1;
1922 xudong 1.15     
1923 mbobra 1.14 	DRMS_Segment_t *bx_errSeg = drms_segment_lookup(inRec, BP_ERR_SEG_CEA);
1924             	DRMS_Array_t *bx_errArray = drms_segment_read(bx_errSeg, DRMS_TYPE_FLOAT, &status);
1925             	float *bx_err = (float *) bx_errArray->data;		// bx_err
1926 xudong 1.1  	
1927             	// Get emphemeris
1928 mbobra 1.16 	float  cdelt1_orig = drms_getkey_float(inRec, "CDELT1",   &status);
1929 xudong 1.9  	float  dsun_obs    = drms_getkey_float(inRec, "DSUN_OBS",   &status);
1930 mbobra 1.16 	double rsun_ref    = drms_getkey_double(inRec, "RSUN_REF", &status);
1931             	double rsun_obs    = drms_getkey_double(inRec, "RSUN_OBS", &status);
1932             	float imcrpix1     = drms_getkey_float(inRec, "IMCRPIX1", &status);
1933             	float imcrpix2     = drms_getkey_float(inRec, "IMCRPIX2", &status);
1934             	float crpix1       = drms_getkey_float(inRec, "CRPIX1", &status);
1935             	float crpix2       = drms_getkey_float(inRec, "CRPIX2", &status);
1936 xudong 1.23     
1937                 // convert cdelt1_orig from degrees to arcsec
1938                 float cdelt1       = (atan((rsun_ref*cdelt1_orig*RADSINDEG)/(dsun_obs)))*(1/RADSINDEG)*(3600.);
1939                 int nx1 = nx*cdelt1/2;
1940                 int ny1 = ny*cdelt1/2;
1941                 
1942 xudong 1.15 	// Temp arrays
1943 mbobra 1.14 	float *bh      = (float *) (malloc(nxny * sizeof(float)));
1944             	float *bt      = (float *) (malloc(nxny * sizeof(float)));
1945             	float *jz      = (float *) (malloc(nxny * sizeof(float)));
1946 xudong 1.9  	float *jz_smooth = (float *) (malloc(nxny * sizeof(float)));
1947 mbobra 1.14 	float *bpx     = (float *) (malloc(nxny * sizeof(float)));
1948             	float *bpy     = (float *) (malloc(nxny * sizeof(float)));
1949             	float *bpz     = (float *) (malloc(nxny * sizeof(float)));
1950             	float *derx    = (float *) (malloc(nxny * sizeof(float)));
1951             	float *dery    = (float *) (malloc(nxny * sizeof(float)));
1952 xudong 1.1  	float *derx_bt = (float *) (malloc(nxny * sizeof(float)));
1953             	float *dery_bt = (float *) (malloc(nxny * sizeof(float)));
1954             	float *derx_bh = (float *) (malloc(nxny * sizeof(float)));
1955             	float *dery_bh = (float *) (malloc(nxny * sizeof(float)));
1956             	float *derx_bz = (float *) (malloc(nxny * sizeof(float)));
1957             	float *dery_bz = (float *) (malloc(nxny * sizeof(float)));
1958 mbobra 1.14 	float *bt_err  = (float *) (malloc(nxny * sizeof(float)));
1959             	float *bh_err  = (float *) (malloc(nxny * sizeof(float)));
1960 xudong 1.23     float *jz_err  = (float *) (malloc(nxny * sizeof(float)));
1961                 float *jz_err_squared = (float *) (malloc(nxny * sizeof(float)));
1962                 float *jz_err_squared_smooth = (float *) (malloc(nxny * sizeof(float)));
1963                 float *jz_rms_err = (float *) (malloc(nxny * sizeof(float)));
1964                 
1965                 // malloc some arrays for the R parameter calculation
1966                 float *rim = (float *)malloc(nx1*ny1*sizeof(float));
1967                 float *p1p0 = (float *)malloc(nx1*ny1*sizeof(float));
1968                 float *p1n0 = (float *)malloc(nx1*ny1*sizeof(float));
1969                 float *p1p = (float *)malloc(nx1*ny1*sizeof(float));
1970                 float *p1n = (float *)malloc(nx1*ny1*sizeof(float));
1971                 float *p1 = (float *)malloc(nx1*ny1*sizeof(float));
1972                 float *pmap = (float *)malloc(nx1*ny1*sizeof(float));
1973                 
1974 arta   1.22 	//spaceweather quantities computed
1975 xudong 1.15 	if (computeAbsFlux(bz_err, bz , dims, &(swKeys_ptr->absFlux), &(swKeys_ptr->mean_vf),  &(swKeys_ptr->mean_vf_err),
1976                                    &(swKeys_ptr->count_mask), mask, bitmask, cdelt1, rsun_ref, rsun_obs))
1977                 {
1978 xudong 1.1  		swKeys_ptr->absFlux = DRMS_MISSING_FLOAT;		// If fail, fill in NaN
1979             		swKeys_ptr->mean_vf = DRMS_MISSING_FLOAT;
1980 xudong 1.15         swKeys_ptr->mean_vf_err = DRMS_MISSING_FLOAT;
1981                     swKeys_ptr->count_mask  = DRMS_MISSING_INT;
1982 xudong 1.1  	}
1983 xudong 1.15     
1984 xudong 1.1  	for (int i = 0; i < nxny; i++) bpz[i] = bz[i];
1985 xudong 1.15 	greenpot(bpx, bpy, bpz, nx, ny);
1986 xudong 1.1  	
1987 mbobra 1.14 	computeBh(bx_err, by_err, bh_err, bx, by, bz, bh, dims, &(swKeys_ptr->mean_hf), mask, bitmask);
1988 xudong 1.15     
1989 mbobra 1.14 	if (computeGamma(bz_err, bh_err, bx, by, bz, bh, dims, &(swKeys_ptr->mean_gamma), &(swKeys_ptr->mean_gamma_err),mask, bitmask))
1990 xudong 1.15 	{
1991                     swKeys_ptr->mean_gamma     =  DRMS_MISSING_FLOAT;
1992                     swKeys_ptr->mean_gamma_err =  DRMS_MISSING_FLOAT;
1993                 }
1994 xudong 1.1  	
1995 mbobra 1.14 	computeB_total(bx_err, by_err, bz_err, bt_err, bx, by, bz, bt, dims, mask, bitmask);
1996 xudong 1.1  	
1997 mbobra 1.14 	if (computeBtotalderivative(bt, dims, &(swKeys_ptr->mean_derivative_btotal), mask, bitmask, derx_bt, dery_bt, bt_err, &(swKeys_ptr->mean_derivative_btotal_err)))
1998 xudong 1.15     {
1999 xudong 1.1  		swKeys_ptr->mean_derivative_btotal = DRMS_MISSING_FLOAT;
2000 mbobra 1.14 		swKeys_ptr->mean_derivative_btotal_err = DRMS_MISSING_FLOAT;
2001 xudong 1.15     }
2002 xudong 1.1  	
2003 mbobra 1.14 	if (computeBhderivative(bh, bh_err, dims, &(swKeys_ptr->mean_derivative_bh), &(swKeys_ptr->mean_derivative_bh_err), mask, bitmask, derx_bh, dery_bh))
2004 xudong 1.15     {
2005 xudong 1.1  		swKeys_ptr->mean_derivative_bh = DRMS_MISSING_FLOAT;
2006 xudong 1.15         swKeys_ptr->mean_derivative_bh_err = DRMS_MISSING_FLOAT;
2007 mbobra 1.14 	}
2008 xudong 1.15     
2009 mbobra 1.14 	if (computeBzderivative(bz, bz_err, dims, &(swKeys_ptr->mean_derivative_bz), &(swKeys_ptr->mean_derivative_bz_err), mask, bitmask, derx_bz, dery_bz))
2010 xudong 1.15     {
2011 xudong 1.1  		swKeys_ptr->mean_derivative_bz = DRMS_MISSING_FLOAT; // If fail, fill in NaN
2012 xudong 1.15         swKeys_ptr->mean_derivative_bz_err = DRMS_MISSING_FLOAT;
2013                 }
2014 xudong 1.1  	
2015 xudong 1.15 	computeJz(bx_err, by_err, bx, by, dims, jz, jz_err, jz_err_squared, mask, bitmask, cdelt1, rsun_ref, rsun_obs,
2016                           derx, dery);
2017                 
2018                 
2019                 if(computeJzsmooth(bx, by, dims, jz, jz_smooth, jz_err, jz_rms_err, jz_err_squared_smooth, &(swKeys_ptr->mean_jz),
2020                                    &(swKeys_ptr->mean_jz_err), &(swKeys_ptr->us_i), &(swKeys_ptr->us_i_err), mask, bitmask, cdelt1,
2021                                    rsun_ref, rsun_obs, derx, dery))
2022                 {
2023                     swKeys_ptr->mean_jz            = DRMS_MISSING_FLOAT;
2024 mbobra 1.14 		swKeys_ptr->us_i               = DRMS_MISSING_FLOAT;
2025 xudong 1.15         swKeys_ptr->mean_jz_err        = DRMS_MISSING_FLOAT;
2026                     swKeys_ptr->us_i_err           = DRMS_MISSING_FLOAT;
2027 xudong 1.1  	}
2028 xudong 1.15     
2029 mbobra 1.14 	if (computeAlpha(jz_err, bz_err, bz, dims, jz, jz_smooth, &(swKeys_ptr->mean_alpha), &(swKeys_ptr->mean_alpha_err), mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2030 xudong 1.15     {
2031 mbobra 1.14 		swKeys_ptr->mean_alpha         = DRMS_MISSING_FLOAT;
2032 xudong 1.15         swKeys_ptr->mean_alpha_err     = DRMS_MISSING_FLOAT;
2033                 }
2034 mbobra 1.14 	
2035 xudong 1.15 	if (computeHelicity(jz_err, jz_rms_err, bz_err, bz, dims, jz, &(swKeys_ptr->mean_ih), &(swKeys_ptr->mean_ih_err), &(swKeys_ptr->total_us_ih), &(swKeys_ptr->total_abs_ih),
2036                                     &(swKeys_ptr->total_us_ih_err), &(swKeys_ptr->total_abs_ih_err), mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2037                 {
2038             		swKeys_ptr->mean_ih            = DRMS_MISSING_FLOAT;
2039 mbobra 1.14 		swKeys_ptr->total_us_ih        = DRMS_MISSING_FLOAT;
2040               		swKeys_ptr->total_abs_ih       = DRMS_MISSING_FLOAT;
2041 xudong 1.15         swKeys_ptr->mean_ih_err        = DRMS_MISSING_FLOAT;
2042                     swKeys_ptr->total_us_ih_err    = DRMS_MISSING_FLOAT;
2043                     swKeys_ptr->total_abs_ih_err   = DRMS_MISSING_FLOAT;
2044 xudong 1.1  	}
2045 xudong 1.15     
2046             	if (computeSumAbsPerPolarity(jz_err, bz_err, bz, jz, dims, &(swKeys_ptr->totaljz), &(swKeys_ptr->totaljz_err),
2047 mbobra 1.5  								 mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2048 xudong 1.15     {
2049 mbobra 1.14 		swKeys_ptr->totaljz            = DRMS_MISSING_FLOAT;
2050 xudong 1.15         swKeys_ptr->totaljz_err        = DRMS_MISSING_FLOAT;
2051 mbobra 1.14 	}
2052 xudong 1.6  	
2053 xudong 1.15 	if (computeFreeEnergy(bx_err, by_err, bx, by, bpx, bpy, dims,
2054             						  &(swKeys_ptr->meanpot), &(swKeys_ptr->meanpot_err), &(swKeys_ptr->totpot), &(swKeys_ptr->totpot_err),
2055             						  mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2056                 {
2057 mbobra 1.14 		swKeys_ptr->meanpot            = DRMS_MISSING_FLOAT; // If fail, fill in NaN
2058             		swKeys_ptr->totpot             = DRMS_MISSING_FLOAT;
2059 xudong 1.15         swKeys_ptr->meanpot_err        = DRMS_MISSING_FLOAT;
2060                     swKeys_ptr->totpot_err         = DRMS_MISSING_FLOAT;
2061 xudong 1.1  	}
2062 xudong 1.15     
2063 xudong 1.24     
2064 mbobra 1.18 	if (computeShearAngle(bx_err, by_err, bz_err, bx, by, bz, bpx, bpy, bpz, dims,
2065 xudong 1.15 						  &(swKeys_ptr->meanshear_angle), &(swKeys_ptr->meanshear_angle_err), &(swKeys_ptr->area_w_shear_gt_45),
2066 mbobra 1.5  						  mask, bitmask)) {
2067 mbobra 1.14 		swKeys_ptr->meanshear_angle    = DRMS_MISSING_FLOAT; // If fail, fill in NaN
2068 xudong 1.1  		swKeys_ptr->area_w_shear_gt_45 = DRMS_MISSING_FLOAT;
2069 xudong 1.15         swKeys_ptr->meanshear_angle_err= DRMS_MISSING_FLOAT;
2070 xudong 1.1  	}
2071 xudong 1.23     
2072 xudong 1.24     /*
2073 xudong 1.23 	if (computeR(bz_err, los , dims, &(swKeys_ptr->Rparam), cdelt1, rim, p1p0, p1n0,
2074                              p1p, p1n, p1, pmap, nx1, ny1))
2075                 {
2076             		swKeys_ptr->Rparam = DRMS_MISSING_FLOAT;		// If fail, fill in NaN
2077             	}
2078 xudong 1.24     */
2079 xudong 1.6  	
2080 mbobra 1.14 	// Clean up the arrays
2081 xudong 1.1  	
2082 xudong 1.6  	drms_free_array(bitmaskArray);		// Dec 18 2012 Xudong
2083 xudong 1.1  	drms_free_array(maskArray);
2084 xudong 1.15 	drms_free_array(bxArray);
2085 xudong 1.1  	drms_free_array(byArray);
2086             	drms_free_array(bzArray);
2087 xudong 1.24     drms_free_array(losArray);          // Mar 7
2088                 drms_free_array(bx_errArray);
2089             	drms_free_array(by_errArray);
2090             	drms_free_array(bz_errArray);
2091 xudong 1.1  	
2092 xudong 1.9  	free(bh); free(bt); free(jz); free(jz_smooth);
2093 xudong 1.1  	free(bpx); free(bpy); free(bpz);
2094 xudong 1.15 	free(derx); free(dery);
2095             	free(derx_bt); free(dery_bt);
2096             	free(derx_bz); free(dery_bz);
2097 xudong 1.1  	free(derx_bh); free(dery_bh);
2098 mbobra 1.14 	free(bt_err); free(bh_err);  free(jz_err);
2099 arta   1.22     free(jz_err_squared); free(jz_rms_err);
2100                 free(jz_err_squared_smooth);
2101 xudong 1.23     
2102                 free(rim);
2103                 free(p1p0);
2104                 free(p1n0);
2105                 free(p1p);
2106                 free(p1n);
2107                 free(p1);
2108                 free(pmap);
2109                 
2110 xudong 1.1  }
2111             
2112 xudong 1.15 /*
2113 xudong 1.1   * Set space weather indices, no error checking for now
2114              *
2115              */
2116             
2117             void setSWIndex(DRMS_Record_t *outRec, struct swIndex *swKeys_ptr)
2118             {
2119 mbobra 1.14 	drms_setkey_float(outRec, "USFLUX",  swKeys_ptr->mean_vf);
2120 xudong 1.1  	drms_setkey_float(outRec, "MEANGAM", swKeys_ptr->mean_gamma);
2121             	drms_setkey_float(outRec, "MEANGBT", swKeys_ptr->mean_derivative_btotal);
2122             	drms_setkey_float(outRec, "MEANGBH", swKeys_ptr->mean_derivative_bh);
2123             	drms_setkey_float(outRec, "MEANGBZ", swKeys_ptr->mean_derivative_bz);
2124             	drms_setkey_float(outRec, "MEANJZD", swKeys_ptr->mean_jz);
2125             	drms_setkey_float(outRec, "TOTUSJZ", swKeys_ptr->us_i);
2126             	drms_setkey_float(outRec, "MEANALP", swKeys_ptr->mean_alpha);
2127             	drms_setkey_float(outRec, "MEANJZH", swKeys_ptr->mean_ih);
2128             	drms_setkey_float(outRec, "TOTUSJH", swKeys_ptr->total_us_ih);
2129             	drms_setkey_float(outRec, "ABSNJZH", swKeys_ptr->total_abs_ih);
2130             	drms_setkey_float(outRec, "SAVNCPP", swKeys_ptr->totaljz);
2131             	drms_setkey_float(outRec, "MEANPOT", swKeys_ptr->meanpot);
2132 mbobra 1.14 	drms_setkey_float(outRec, "TOTPOT",  swKeys_ptr->totpot);
2133 xudong 1.1  	drms_setkey_float(outRec, "MEANSHR", swKeys_ptr->meanshear_angle);
2134             	drms_setkey_float(outRec, "SHRGT45", swKeys_ptr->area_w_shear_gt_45);
2135 arta   1.22     drms_setkey_float(outRec, "CMASK",   swKeys_ptr->count_mask);
2136                 drms_setkey_float(outRec, "ERRBT",   swKeys_ptr->mean_derivative_btotal_err);
2137                 drms_setkey_float(outRec, "ERRVF",   swKeys_ptr->mean_vf_err);
2138                 drms_setkey_float(outRec, "ERRGAM",  swKeys_ptr->mean_gamma_err);
2139                 drms_setkey_float(outRec, "ERRBH",   swKeys_ptr->mean_derivative_bh_err);
2140                 drms_setkey_float(outRec, "ERRBZ",   swKeys_ptr->mean_derivative_bz_err);
2141                 drms_setkey_float(outRec, "ERRJZ",   swKeys_ptr->mean_jz_err);
2142                 drms_setkey_float(outRec, "ERRUSI",  swKeys_ptr->us_i_err);
2143                 drms_setkey_float(outRec, "ERRALP",  swKeys_ptr->mean_alpha_err);
2144                 drms_setkey_float(outRec, "ERRMIH",  swKeys_ptr->mean_ih_err);
2145                 drms_setkey_float(outRec, "ERRTUI",  swKeys_ptr->total_us_ih_err);
2146                 drms_setkey_float(outRec, "ERRTAI",  swKeys_ptr->total_abs_ih_err);
2147                 drms_setkey_float(outRec, "ERRJHT",  swKeys_ptr->totaljz_err);
2148                 drms_setkey_float(outRec, "ERRMPOT", swKeys_ptr->meanpot_err);
2149                 drms_setkey_float(outRec, "ERRTPOT", swKeys_ptr->totpot_err);
2150                 drms_setkey_float(outRec, "ERRMSHA", swKeys_ptr->meanshear_angle_err);
2151 xudong 1.23     drms_setkey_float(outRec, "R_VALUE", swKeys_ptr->Rparam);
2152 xudong 1.1  };
2153             
2154 xudong 1.15 /*
2155 xudong 1.1   * Set all keywords, no error checking for now
2156              *
2157              */
2158             
2159 xudong 1.23 void setKeys(DRMS_Record_t *outRec, DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo)
2160 xudong 1.1  {
2161 xudong 1.23     
2162             	copy_me_keys(bharpRec, outRec);
2163             	copy_patch_keys(mharpRec, outRec);      // Dec 30
2164             	copy_geo_keys(mharpRec, outRec);        // Dec 30
2165             	copy_ambig_keys(bharpRec, outRec);
2166                 
2167 xudong 1.15     int status = 0;
2168             	
2169 xudong 1.23 	// Change a few geometry keywords for CEA & cutout records
2170             	if (mInfo != NULL) {        // CEA
2171 xudong 1.15         
2172                     drms_setkey_float(outRec, "CRPIX1", mInfo->ncol/2. + 0.5);
2173             		drms_setkey_float(outRec, "CRPIX2", mInfo->nrow/2. + 0.5);
2174             		
2175             		drms_setkey_float(outRec, "CRVAL1", mInfo->xc);
2176             		drms_setkey_float(outRec, "CRVAL2", mInfo->yc);
2177             		drms_setkey_float(outRec, "CDELT1", mInfo->xscale);
2178             		drms_setkey_float(outRec, "CDELT2", mInfo->yscale);
2179             		drms_setkey_string(outRec, "CUNIT1", "degree");
2180             		drms_setkey_string(outRec, "CUNIT2", "degree");
2181             		
2182             		char key[64];
2183             		snprintf (key, 64, "CRLN-%s", wcsCode[(int) mInfo->proj]);
2184             		drms_setkey_string(outRec, "CTYPE1", key);
2185             		snprintf (key, 64, "CRLT-%s", wcsCode[(int) mInfo->proj]);
2186             		drms_setkey_string(outRec, "CTYPE2", key);
2187             		drms_setkey_float(outRec, "CROTA2", 0.0);
2188 xudong 1.23         
2189                     // Jan 2 2014 XS
2190                     int nSeg = ARRLENGTH(CEASegs);
2191                     for (int iSeg = 0; iSeg < nSeg; iSeg++) {
2192                         DRMS_Segment_t *outSeg = NULL;
2193                         outSeg = drms_segment_lookup(outRec, CEASegs[iSeg]);
2194                         if (!outSeg) continue;
2195                         // Set Bunit
2196                         char bunit_xxx[20];
2197                         sprintf(bunit_xxx, "BUNIT_%03d", iSeg);
2198                         //printf("%s, %s\n", bunit_xxx, CEABunits[iSeg]);
2199                         drms_setkey_string(outRec, bunit_xxx, CEABunits[iSeg]);
2200                     }
2201 xudong 1.15 		
2202 xudong 1.23 	} else {        // Cutout
2203 xudong 1.15         
2204 xudong 1.23         float disk_xc, disk_yc;
2205                     if (fullDisk) {
2206                         disk_xc = drms_getkey_float(bharpRec, "CRPIX1", &status);
2207                         disk_yc = drms_getkey_float(bharpRec, "CRPIX2", &status);
2208                     } else {
2209                         disk_xc = drms_getkey_float(mharpRec, "IMCRPIX1", &status);
2210                         disk_yc = drms_getkey_float(mharpRec, "IMCRPIX2", &status);
2211                     }
2212                     float x_ll = drms_getkey_float(mharpRec, "CRPIX1", &status);
2213                     float y_ll = drms_getkey_float(mharpRec, "CRPIX2", &status);
2214 xudong 1.15         // Defined as disk center's pixel address wrt lower-left of cutout
2215                     drms_setkey_float(outRec, "CRPIX1", disk_xc - x_ll + 1.);
2216             		drms_setkey_float(outRec, "CRPIX2", disk_yc - y_ll + 1.);
2217             		// Always 0.
2218             		drms_setkey_float(outRec, "CRVAL1", 0);
2219             		drms_setkey_float(outRec, "CRVAL2", 0);
2220 xudong 1.23         
2221                     // Jan 2 2014 XS
2222                     int nSeg = ARRLENGTH(CutSegs);
2223                     for (int iSeg = 0; iSeg < nSeg; iSeg++) {
2224                         DRMS_Segment_t *outSeg = NULL;
2225                         outSeg = drms_segment_lookup(outRec, CutSegs[iSeg]);
2226                         if (!outSeg) continue;
2227                         // Set Bunit
2228                         char bunit_xxx[20];
2229                         sprintf(bunit_xxx, "BUNIT_%03d", iSeg);
2230                         //printf("%s, %s\n", bunit_xxx, CutBunits[iSeg]);
2231                         drms_setkey_string(outRec, bunit_xxx, CutBunits[iSeg]);
2232                     }
2233                     
2234 xudong 1.15 		
2235             	}
2236 xudong 1.23     
2237                 TIME val, trec, tnow, UNIX_epoch = -220924792.000; /* 1970.01.01_00:00:00_UTC */
2238                 tnow = (double)time(NULL);
2239                 tnow += UNIX_epoch;
2240             	
2241                 val = drms_getkey_time(bharpRec, "DATE", &status);
2242                 drms_setkey_time(outRec, "DATE_B", val);
2243                 drms_setkey_time(outRec, "DATE", tnow);
2244             	
2245                 // set cvs commit version into keyword HEADER
2246 xudong 1.24     char *cvsinfo  = strdup("$Id: sharp.c,v 1.23 2014/03/05 19:39:32 xudong Exp $");
2247 xudong 1.23     char *cvsinfo2 = sw_functions_version();
2248                 char cvsinfoall[2048];
2249                 strcat(cvsinfoall,cvsinfo);
2250                 strcat(cvsinfoall,"\n");
2251                 strcat(cvsinfoall,cvsinfo2);
2252                 status = drms_setkey_string(outRec, "CODEVER7", cvsinfoall);
2253 xudong 1.6  	
2254 xudong 1.1  };
2255             
2256             
2257             /* ############# Nearest neighbour interpolation ############### */
2258             
2259             float nnb (float *f, int nx, int ny, double x, double y)
2260             {
2261             	
2262             	if (x <= -0.5 || y <= -0.5 || x > nx - 0.5 || y > ny - 0.5)
2263             		return DRMS_MISSING_FLOAT;
2264             	int ilow = floor (x);
2265             	int jlow = floor (y);
2266             	int i = ((x - ilow) > 0.5) ? ilow + 1 : ilow;
2267             	int j = ((y - jlow) > 0.5) ? jlow + 1 : jlow;
2268             	return f[j * nx + i];
2269             	
2270             }
2271             
2272             /* ################## Wrapper for Jesper's rebin code ################## */
2273             
2274             void frebin (float *image_in, float *image_out, int nx, int ny, int nbin, int gauss)
2275 xudong 1.1  {
2276             	
2277             	struct fresize_struct fresizes;
2278             	int nxout, nyout, xoff, yoff;
2279             	int nlead = nx;
2280             	
2281             	nxout = nx / nbin; nyout = ny / nbin;
2282             	if (gauss && nbin != 1)
2283             		init_fresize_gaussian(&fresizes, (nbin / 2), (nbin / 2 * 2), nbin);		// for nbin=3, sigma=1, half truncate width=2
2284             	else
2285             		init_fresize_bin(&fresizes, nbin);
2286             	xoff = nbin / 2 + nbin / 2;
2287             	yoff = nbin / 2 + nbin / 2;
2288             	fresize(&fresizes, image_in, image_out, nx, ny, nlead, nxout, nyout, nxout, xoff, yoff, DRMS_MISSING_FLOAT);
2289             	
2290             }

Karen Tian
Powered by
ViewCVS 0.9.4