Esempio n. 1
0
static void show_cert(struct tls_cert *cert, char *buf, size_t buflen)
{
	if (!cert) {
		snprintf(buf, buflen, "no cert");
		return;
	}
	show_append(buf, buflen, "Subject: ", "");
	show_dname(buf, buflen, &cert->subject);
	show_append(buf, buflen, " Issuer: ", "");
	show_dname(buf, buflen, &cert->issuer);
	show_append(buf, buflen, " Serial: ", cert->serial);
	show_append(buf, buflen, " NotBefore: ", isotime(NULL, 0, cert->not_before));
	show_append(buf, buflen, " NotAfter: ", isotime(NULL, 0, cert->not_after));
}
Esempio n. 2
0
int main(int argc, char *argv[])
{
	char fname[200];
	
	FILE *f;
	int bc = strtoul(argv[1], NULL, 0);
	static struct tspoint tp[20000];
	int i;

	snprintf(fname, sizeof(fname), "/sys/kernel/debug/cbmia/tspoints%d", bc);
	f = fopen(fname, "rb");
	fread(tp, sizeof(struct tspoint), 20000, f);
	printf("sizeof(tp) = %zd\n", sizeof(tp));

	printf("bc:%d    rti %18s %18s %18s %18s\n", bc, "strtx", "wrttx", "inttx", "endtx");
	for (i = 0; i < 20000; i++) {
		printf("bc:%u rti:%02u %10u.%06u %s %6u %6u %6u\n",
			bc, tp[i].rti,
			sec(tp[i].start_tx), usec(tp[i].start_tx),
			isotime(tp[i].start_tx),
			usec(tp[i].write_tx - tp[i].start_tx),
			usec(tp[i].int_tx - tp[i].write_tx),
			usec(tp[i].end_tx - tp[i].int_tx));
	}
	return 0;
}
Esempio n. 3
0
static JsonNode *line_to_location(char *line)
{
	JsonNode *json, *o, *j;
	char *ghash;
	char tstamp[64], *bp;
	double lat, lon;
	long tst;

	snprintf(tstamp, 21, "%s", line);

	if ((bp = strchr(line, '{')) == NULL)
		return (NULL);

	if ((json = json_decode(bp)) == NULL) {
		return (NULL);
	}

	if ((j = json_find_member(json, "_type")) == NULL) {
		json_delete(json);
		return (NULL);
	}
	if (j->tag != JSON_STRING || strcmp(j->string_, "location") != 0) {
		json_delete(json);
		return (NULL);
	}

	o = json_mkobject();

	if (json_copy_to_object(o, json, FALSE) == FALSE) {
		json_delete(o);
		json_delete(json);
		return (NULL);
	}
	json_delete(json);	/* Done with this -- we've copied it. */

	lat = lon = 0.0;
	if ((j = json_find_member(o, "lat")) != NULL) {
		lat = j->number_;
	}
	if ((j = json_find_member(o, "lon")) != NULL) {
		lon = j->number_;
	}

	if ((ghash = geohash_encode(lat, lon, geohash_prec())) != NULL) {
		json_append_member(o, "ghash", json_mkstring(ghash));
		get_geo(o, ghash);
		free(ghash);
	}

	json_append_member(o, "isorcv", json_mkstring(tstamp));

	tst = 0L;
	if ((j = json_find_member(o, "tst")) != NULL) {
		tst = j->number_;
	}
	json_append_member(o, "isotst", json_mkstring(isotime(tst)));

	return (o);
}
Esempio n. 4
0
/*
 * Get event time at index from event list
 */
char* mod_eventList_get(uint8_t index)
{
	if(index < ME_EVENTS) {
		const time_t	event = me_events[index];
		const struct tm* timeStrut = localtime(&event);
		return isotime(timeStrut);
	} else {
		return strcpy(me_eventStr,"No Event");				// NULL terminated string.
	}
}
Esempio n. 5
0
int
main()
{

	time_t          t;
	struct tm * tmptr;
	char           *cp;

	time(&t);
	tmptr = localtime(&t);
	cp = isotime(tmptr);
	if (strcmp(Y2K_isostring, cp)) return (__LINE__);

	t = 0xffffffff;
	tmptr = localtime(&t);
	cp = isotime(tmptr);
	if (strcmp(end_isostring, cp)) return (__LINE__);

	return 0;
}
Esempio n. 6
0
void append_device_details(JsonNode *userlist, char *user, char *device)
{
	char path[BUFSIZ];
	JsonNode *node, *last, *card;

	snprintf(path, BUFSIZ, "%s/last/%s/%s/%s-%s.json",
		STORAGEDIR, user, device, user, device);

	last = json_mkobject();
	if (json_copy_from_file(last, path) == TRUE) {
		JsonNode *tst;

		if ((tst = json_find_member(last, "tst")) != NULL) {
			json_append_member(last, "isotst", json_mkstring(isotime(tst->number_)));
		}

		json_append_element(userlist, last);
	} else {
		json_delete(last);
	}

	snprintf(path, BUFSIZ, "%s/cards/%s/%s.json",
		STORAGEDIR, user, user);

	card = json_mkobject();
	if (json_copy_from_file(card, path) == TRUE) {
		json_copy_to_object(last, card, FALSE);
	}
	json_delete(card);

	if ((node = json_find_member(last, "ghash")) != NULL) {
		if (node->tag == JSON_STRING) {
			get_geo(last, node->string_);
		}
	}
}
Esempio n. 7
0
void append_device_details(JsonNode *userlist, char *user, char *device)
{
	char path[BUFSIZ];
	JsonNode *node, *last;

	snprintf(path, BUFSIZ, "%s/last/%s/%s/%s-%s.json",
		STORAGEDIR, user, device, user, device);

	last = json_mkobject();
	if (json_copy_from_file(last, path) == TRUE) {
		JsonNode *tst;

		if ((tst = json_find_member(last, "tst")) != NULL) {
			json_append_member(last, "isotst", json_mkstring(isotime(tst->number_)));
			json_append_member(last, "disptst", json_mkstring(disptime(tst->number_)));
		}
	}

	append_card_to_object(last, user, device);


	if ((node = json_find_member(last, "ghash")) != NULL) {
		if (node->tag == JSON_STRING) {
			get_geo(last, node->string_);
		}
	}

	/* Extra data */
	snprintf(path, BUFSIZ, "%s/last/%s/%s/extra.json",
		STORAGEDIR, user, device);
	json_copy_from_file(last, path);
#if WITH_GREENWICH
	get_gw_data(user, device, last);
#endif
	json_append_element(userlist, last);
}
Esempio n. 8
0
void
print_header (void)
{
  char modes[11];
  char *timestamp;
  char uform[11], gform[11];	/* these hold formatted ints */
  char *user, *group;
  char size[24];		/* holds a formatted long or maj, min */
  time_t longie;		/* to make ctime() call portable */
  int pad;
  char *name;

  if (block_number_option)
    fprintf (stdlis, _("block %10ld: "), current_block_ordinal ());

  if (verbose_option <= 1)
    {
      /* Just the fax, mam.  */

      char *quoted_name = quote_copy_string (current_file_name);

      if (quoted_name)
	{
	  fprintf (stdlis, "%s\n", quoted_name);
	  free (quoted_name);
	}
      else
	fprintf (stdlis, "%s\n", current_file_name);
    }
  else
    {
      /* File type and modes.  */

      modes[0] = '?';
      switch (current_header->header.typeflag)
	{
	case GNUTYPE_VOLHDR:
	  modes[0] = 'V';
	  break;

	case GNUTYPE_MULTIVOL:
	  modes[0] = 'M';
	  break;

	case GNUTYPE_NAMES:
	  modes[0] = 'N';
	  break;

	case GNUTYPE_LONGNAME:
	case GNUTYPE_LONGLINK:
	  ERROR ((0, 0, _("Visible longname error")));
	  break;

	case GNUTYPE_SPARSE:
	case REGTYPE:
	case AREGTYPE:
	case LNKTYPE:
	  modes[0] = '-';
	  if (current_file_name[strlen (current_file_name) - 1] == '/')
	    modes[0] = 'd';
	  break;
	case GNUTYPE_DUMPDIR:
	  modes[0] = 'd';
	  break;
	case DIRTYPE:
	  modes[0] = 'd';
	  break;
	case SYMTYPE:
	  modes[0] = 'l';
	  break;
	case BLKTYPE:
	  modes[0] = 'b';
	  break;
	case CHRTYPE:
	  modes[0] = 'c';
	  break;
	case FIFOTYPE:
	  modes[0] = 'p';
	  break;
	case CONTTYPE:
	  modes[0] = 'C';
	  break;
	}

      decode_mode ((unsigned) current_stat.st_mode, modes + 1);

      /* Timestamp.  */

      longie = current_stat.st_mtime;
#if USE_OLD_CTIME
      timestamp = ctime (&longie);
      timestamp[16] = '\0';
      timestamp[24] = '\0';
#else
      timestamp = isotime (&longie);
      timestamp[16] = '\0';
#endif

      /* User and group names.  */

      if (*current_header->header.uname && current_format != V7_FORMAT)
	user = current_header->header.uname;
      else
	{
	  user = uform;
	  sprintf (uform, "%ld", from_oct (8, current_header->header.uid));
	}

      if (*current_header->header.gname && current_format != V7_FORMAT)
	group = current_header->header.gname;
      else
	{
	  group = gform;
	  sprintf (gform, "%ld", from_oct (8, current_header->header.gid));
	}

      /* Format the file size or major/minor device numbers.  */

      switch (current_header->header.typeflag)
	{
#if defined(S_IFBLK) || defined(S_IFCHR)
	case CHRTYPE:
	case BLKTYPE:
	  sprintf (size, "%d,%d",
		   major (current_stat.st_rdev), minor (current_stat.st_rdev));
	  break;
#endif
	case GNUTYPE_SPARSE:
	  sprintf (size, "%lld",
		   llfrom_oct (sizeof current_header->oldgnu_header.realsize,
				current_header->oldgnu_header.realsize));
	  break;
	default:
	  sprintf (size, "%lld", (long long) current_stat.st_size);
	}

      /* Figure out padding and print the whole line.  */

      pad = strlen (user) + strlen (group) + strlen (size) + 1;
      if (pad > ugswidth)
	ugswidth = pad;

#if USE_OLD_CTIME
      fprintf (stdlis, "%s %s/%s %*s%s %s %s",
	       modes, user, group, ugswidth - pad, "",
	       size, timestamp + 4, timestamp + 20);
#else
      fprintf (stdlis, "%s %s/%s %*s%s %s",
	       modes, user, group, ugswidth - pad, "", size, timestamp);
#endif

      name = quote_copy_string (current_file_name);
      if (name)
	{
	  fprintf (stdlis, " %s", name);
	  free (name);
	}
      else
	fprintf (stdlis, " %s", current_file_name);

      switch (current_header->header.typeflag)
	{
	case SYMTYPE:
	  name = quote_copy_string (current_link_name);
	  if (name)
	    {
	      fprintf (stdlis, " -> %s\n", name);
	      free (name);
	    }
	  else
	    fprintf (stdlis, " -> %s\n", current_link_name);
	  break;

	case LNKTYPE:
	  name = quote_copy_string (current_link_name);
	  if (name)
	    {
	      fprintf (stdlis, _(" link to %s\n"), name);
	      free (name);
	    }
	  else
	    fprintf (stdlis, _(" link to %s\n"), current_link_name);
	  break;

	default:
	  fprintf (stdlis, _(" unknown file type `%c'\n"),
		   current_header->header.typeflag);
	  break;

	case AREGTYPE:
	case REGTYPE:
	case GNUTYPE_SPARSE:
	case CHRTYPE:
	case BLKTYPE:
	case DIRTYPE:
	case FIFOTYPE:
	case CONTTYPE:
	case GNUTYPE_DUMPDIR:
	  putc ('\n', stdlis);
	  break;

	case GNUTYPE_VOLHDR:
	  fprintf (stdlis, _("--Volume Header--\n"));
	  break;

	case GNUTYPE_MULTIVOL:
	  fprintf (stdlis, _("--Continued at byte %ld--\n"),
		   from_oct (1 + 12, current_header->oldgnu_header.offset));
	  break;

	case GNUTYPE_NAMES:
	  fprintf (stdlis, _("--Mangled file names--\n"));
	  break;
	}
    }
  fflush (stdlis);
}
Esempio n. 9
0
int DoIt(){
 
    /* Variable declarations */

    /* Generic use variables */

    int i,j,k;					/* Generic loop counters */

    /* DRMS/JSOC variables */

	char *harpnum,*time_range;					/* SHARPs ID and time range from module_args[] */
	char *drms_query;							/* The DRMS query we are going to send */
	double umb_sig, pen_sig;					/* Cutoffs for sunspots */
	int num_query_chars;						/* Number of characters in total query for malloc definition */
	CmdParams_t *params=&cmdparams;				/* For the module_args stuff */
	DRMS_RecordSet_t *drms_ids;					/* Holds the id structure of the records */
	DRMS_Record_t *drms_record;					/* Holds specific record information */
	DRMS_Segment_t *drms_segment;				/* Segment information */
	int drms_status;							/* Status variable */
	int num_records;							/* Number of records and variables to get the segment locations we need */
	
	/* cfitsio-related variables */

    fitsfile *c_ptr,*i_ptr;				/* Pointers for FITS files */
    int c_status, i_status;				/* Status checker for opening files */
    int hdu_pos,num_hdus;				/* HDU number and location */
    int needed_hdu;						/* The HDU we want to be on */
    int any_nulls;						/* Nonzero if there are null values in data */
    char i_filename[DRMS_MAXPATHLEN+1],c_filename[DRMS_MAXPATHLEN+1];	/* Containers for the filenames */
    double nulval;							/* Container for what null values in data should be set to */
	

    /* Needed FITS keywords */

    int naxis1,naxis2,naxis;			/* Length of axes */
    double crpix1,crpix2;				/* SHARPs CRPIX is the center of the sun relative to the lower left (fortran: 1,1) of patch */
    double cdelt1		;				/* HMI pixel sizes in as */
    double rsun_obs;					/* Radius of the sun, observed at t_obs */
    double blank;						/* Values of bad data */
    TIME t_obs;							/* Observation time, ZULU */
    char **t_obs_s;						/* String version of observation time */
    long *quality;						/* QUALITY keyword */
    
    /* Data-related variables */
    
    double **con_dat, **inc_dat;			/* Data arrays, size defined once naxis1/2 are known */
    int **p_mask, **n_mask;					/* Mask for each polarity of umbrae within continuum data */ 
    double *c_pixel_strip;					/* Strip of pixels read from the continuum data */
    double *i_pixel_strip;					/* Strip of pixels read from the inclination data */
    long fpixel[2];							/* Holds the location of pixel to be read */
    LONGLONG nelements;						/* Number of elements in a strip to be read (naxis2) */
    FILE *outptr,*bad_outptr;				/* Pointer to the outfile */
    char outfile_name[29];					/* Name of the outfile */
    char bad_outfile_name[24];				/* Name of the outfile for bad quality*/    
    
    /* Variables related to the actual task */
    
    double rllx,rlly;				/* Disk center, patch coordinates */
    double **radius;				/* Array to hold where the Sun's boundaries are, column major order */
    double rsun_pix,xx,yy,r;		/* Variables associated with radial boundaries */
    double umb,pen;					/* Intensity cutoffs for the umbra and penumbra */
    double num_good;				/* The number of nonzero continuum values in a sunspot region */
    double *p_spots,*n_spots;		/* Number of sunspots of each polarity within an active region */
    double mu;						/* Angle from solar center */
    long *t_secs;					/* T_OBS time converted to seconds since UNIX epoch */
    int noaa_ar;					/* Active region number */
    
    /* Initialise variables that need it */

    i=j=k=0;
    drms_status=0;

	/* Grab values from module_args[] */

	harpnum=strdup(params_get_str(params,"harpnum"));
	time_range=strdup(params_get_str(params,"time_range"));
	umb_sig=params_get_double(params,"umb_sig");
	pen_sig=params_get_double(params,"pen_sig");

	/* Now we start the main program. The rough layout is as follows: 
	   
	   1. Query drms. Based on what we learn, either exit or grab what we need from it.
	   2. Loop through the files, determining the number of sunspots in each polarity.
	   3. Print out a table of values at the end.				   */
	
	/* Forge the DRMS query. */
	
	num_query_chars=16+strlen(harpnum);		/* hmi.sharp_720s[] is 16 characters */
	
	if (time_range!="[]"){
		
		num_query_chars+=strlen(time_range);
		
	}
	
	drms_query=calloc(num_query_chars,sizeof(char));
	strcat(drms_query,"hmi.sharp_720s[");
	strcat(drms_query,harpnum);
	strcat(drms_query,"]");
	
	if (time_range!="[]"){
	
		strcat(drms_query,time_range);
		
	}
	
	/* Query DRMS for the records. */
	
	printf("Querying DRMS. This may take some time.\n");
	
	if (!(drms_ids=drms_open_records(drms_env,drms_query,&drms_status))){
		
		printf("No record sets match your criteria. Check your SHARPs ID and your time range.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		free(drms_query);
		return 0;
		
	}

	free(drms_query);

	num_records=drms_ids->n;
	printf("%d records match. Checking to make sure we have the needed data segments.\n",num_records);

	drms_record=drms_ids->records[0];

	if (!(drms_segment_lookup(drms_record,"continuum"))){
		
		printf("Continuum segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}

	if (!(drms_segment_lookup(drms_record,"inclination"))){
		
		printf("Inclination segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}
	
	/* Now we can start. We loop over all records, get the keyword information we need, get the data, and then calculate. */
	
	/* First set the size of some of the pointers that are intended to be arrays. */
	
	/* Data-related arrays */
	p_spots=malloc(num_records*sizeof(double));
	n_spots=malloc(num_records*sizeof(double));
	
	/* Time-related arrays */
	
	t_secs=malloc(num_records*sizeof(long));
	t_obs_s=malloc(num_records*sizeof(char *));
	
	for (i=0;i<num_records;i++){
		
		t_obs_s[i]=malloc(T_OBS_LENGTH*sizeof(char));
		
	}
	
	/* Quality */
	
	quality=malloc(num_records*sizeof(long));
		
	for (k=0;k<num_records;k++){ 

		drms_record=drms_ids->records[k];
		
		/* Check to see if we have data for a particular observation time */
		
		if (!(t_obs=drms_getkey_time(drms_record,"T_OBS",&drms_status))){
					
			printf("Keyword %s not present! Exiting.\n","T_OBS");
			drms_close_records(drms_ids,DRMS_FREE_RECORD);
			return 0;
		
		}
		
		if (time_is_invalid(t_obs)){
			
			printf("Bad record, skipping.\n");
			
		} else {

			if (k == 0){
				
				/* Get active region number for pregame info */
			
				if (!(noaa_ar=drms_getkey_int(drms_record,"NOAA_AR",&drms_status))){
					
					printf("Keyword %s not present! Exiting.\n","NOAA_AR");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
		
				}
				
				/* Create data output filename */
			
				sprintf(outfile_name,"AR%d.spotcount-output.dat",noaa_ar);
				sprintf(bad_outfile_name,"AR%d.bad-quality.dat",noaa_ar);
				
				/* Print out some stats before we run */
			
				printf("Pre-analysis details:\n");
				printf("Analyzing: HARP Number: %s\t NOAA AR: %d\n",harpnum,noaa_ar);
				printf("Output file: %s\n",outfile_name);
			
				if (time_range == "[]"){
				
					printf("We are covering the entire data set.\n");
			
				} else {
				
					printf("Time range: %s\n",time_range);
			
				}

					printf("\n\n");
			
			}
			
			printf("Processing record %d of %d.\n",k+1,num_records);
		
			/* Fill keywords */
			
			if (!(quality[k]=drms_getkey_longlong(drms_record,"QUALITY",&drms_status))){
			
				quality[k]=0;
		
			}
	
			if (!(crpix1=drms_getkey_double(drms_record,"CRPIX1",&drms_status))){
			
				printf("Keyword %s not present! Exiting.\n","CRPIX1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(crpix2=drms_getkey_double(drms_record,"CRPIX2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CRPIX2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(cdelt1=drms_getkey_double(drms_record,"CDELT1",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CDELT1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(rsun_obs=drms_getkey_double(drms_record,"RSUN_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","RSUN_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(blank=drms_getkey_double(drms_record,"BLANK",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","BLANK");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			sprint_ut(t_obs_s[k],t_obs);		/* Convert to string */
			
			if (quality[k] == 0){
		
				/* Ok, now we get the file locations for the data from DRMS. Originally I attempted
				* to pull the data directly from DRMS but there were vague free() and malloc() issues
				* possibly due to icc and multithreading. */
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"continuum"))){
			
					printf("Problem opening the continuum segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,c_filename);
			
				/* naxis1 and naxis2 we get from segment information */
		
				naxis1=(int)drms_segment->axis[0];
				naxis2=(int)drms_segment->axis[1];
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"inclination"))){
			
					printf("Problem opening the inclination segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,i_filename);
		
				/* Now open the FITS files and get to work. */
	
				c_status=i_status=0;

				if (fits_open_file(&c_ptr,c_filename,READONLY,&c_status)){
				
					printf("Cannot open %s! Exiting.\n",c_filename);
					exit(0);

				}

				if (fits_open_file(&i_ptr,i_filename,READONLY,&i_status)){
				
					printf("Cannot open %s! Exiting.\n",i_filename);
					fits_close_file(c_ptr,&c_status);
					exit(0);

				}

				printf(" Opening FITs files.\n");

				/* Walk through the HDUs until we get to one with NAXIS=2 */

				/* Number of headers and which one we are on */

				fits_get_num_hdus(c_ptr,&num_hdus,&c_status);
				fits_get_hdu_num(c_ptr,&hdu_pos);

				/* Find the one with two naxes */

				naxis=0;
			
				for (i=1;i<=num_hdus;i++){
				
					fits_movabs_hdu(c_ptr,i,NULL,&c_status);
					fits_read_key(c_ptr,TINT,"NAXIS",&naxis,NULL,&c_status);
				
					if (naxis == 2){
	
						needed_hdu=i;
	
					}
				}

				/* Set all to the needed HDU */

				if (naxis == 0){
		
					printf("HDU problems: can't find one with the required number of axes.\n");
					fits_close_file(c_ptr,&c_status);
					fits_close_file(i_ptr,&i_status);
					exit(0);

				} else {

					fits_movabs_hdu(c_ptr,needed_hdu,NULL,&c_status);
					fits_movabs_hdu(i_ptr,needed_hdu,NULL,&i_status);

				}

				/* Now set some definite boundaries on arrays to help with memory usage. Arrays are called as con_dat[y][x]. */
	
				p_mask=malloc(naxis2*sizeof(int *));
				n_mask=malloc(naxis2*sizeof(int *));
				con_dat=malloc(naxis2*sizeof(double *));
				inc_dat=malloc(naxis2*sizeof(double *));
				radius=malloc(naxis2*sizeof(double *));
				
				c_pixel_strip=calloc(naxis1,sizeof(double));
				i_pixel_strip=calloc(naxis1,sizeof(double));
	
				for (j=0;j<naxis2;j++){
		
					p_mask[j]=calloc(naxis1,sizeof(int));
					n_mask[j]=calloc(naxis1,sizeof(int));
					con_dat[j]=calloc(naxis1,sizeof(double));
					inc_dat[j]=calloc(naxis1,sizeof(double));
					radius[j]=calloc(naxis1,sizeof(double));
		
				}
    
				/* Next, put data in the arrays, clear out blank values and NaNs from the data */
	
				fpixel[0]=1;		/* cfitsio uses fortran reference instead of c when accessing data */
				nelements=naxis1;
				nulval=0;
				any_nulls=0;
    
				for (j=0;j<naxis2;j++){
		
					fpixel[1]=j+1;	/* Add 1 to account for fortran FITS indexing */
					fits_read_pix(c_ptr,TDOUBLE,fpixel,nelements,&nulval,c_pixel_strip,&any_nulls,&c_status);
					fits_read_pix(i_ptr,TDOUBLE,fpixel,nelements,&nulval,i_pixel_strip,&any_nulls,&i_status);
		
					for (i=0;i<naxis1;i++){
			
						/* Kill blank values if present, if not assign to the correct place in array */
			
						if (c_pixel_strip[i] == blank){
				
							con_dat[j][i]=0.0;
					
						} else {
					
							con_dat[j][i]=c_pixel_strip[i];
			
						}
			
						if (i_pixel_strip[i] == blank){
				
							inc_dat[j][i]=0.0;
				
						} else {
					
							inc_dat[j][i]=i_pixel_strip[i];
			
						}
					
					}
				}
		
				printf(" Analyzing data.\n");
	
				/* We now have filled arrays of data about the SHARPs patch and all of the needed keywords. */
	
				/* Coordinate variable definitions for future use. See the declaration section */
				/* at the front of the code to understand what these refer to. */
	
				rllx=(crpix1-1);
				rlly=(crpix2-1);
	
				/* Fill the radius array, handle limb darkening, find max value in patch. */
	
				rsun_pix=rsun_obs/cdelt1;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
			
						xx=(double)i-rllx;
						yy=(double)j-rlly;
						r=sqrt(xx*xx+yy*yy);
				
						if (r <= rsun_pix){
				
							radius[j][i]=r;
							mu=sqrt(1-pow(r/rsun_pix,2.0));
							con_dat[j][i]=con_dat[j][i]/limb_darken(mu);
					
						}
					}
				}
	
				/* Create the actual masks for sunspot counting */
			
				spotbounds(con_dat,naxis1,naxis2,&umb,&pen,umb_sig,pen_sig);

				num_good=0;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
		
						if ((radius[j][i] > 0)&&(con_dat[j][i] <= pen)&&(con_dat[j][i] > 0)){
				
							num_good++;
			
						}
					}
				}

				p_spots[k]=n_spots[k]=0.0;
	
				if (num_good > 0){
		
					/* We have a region. */
		
					for (i=0;i<naxis1;i++){
					
						for (j=0;j<naxis2;j++){
				
							/* On the solar disk, with continuum values at or below the cutoff for
							* the penumbra */
				
							if ((radius[j][i] > 0)&&(con_dat[j][i] <= umb)&&(con_dat[j][i] > 0)){
						
								/* "Positive" sunspot polarities. */
							
								if (inc_dat[j][i] < 90){
							
									p_mask[j][i]=1;
					
								}
					
								/* "Negative" sunspot polarities. */
					
								if (inc_dat[j][i] > 90){
							
									n_mask[j][i]=1;
					
								}
							}
						}
					}
				
					/* Now find the number of unique spots */
				
					p_spots[k]=connected_component_detect(p_mask,naxis1,naxis2);
					n_spots[k]=connected_component_detect(n_mask,naxis1,naxis2);
			
				}

			
				/* Free up dynamic arrays and close the files for the next iteration. */

				for (i=0;i<naxis2;i++){

					free(p_mask[i]);
					free(n_mask[i]);
					free(con_dat[i]);
					free(inc_dat[i]);
					free(radius[i]);
				
				}

				free(p_mask);
				free(n_mask);
				free(con_dat);
				free(inc_dat);
				free(radius);

				free(c_pixel_strip);
				free(i_pixel_strip);
				
				fits_close_file(c_ptr,&c_status);
				fits_close_file(i_ptr,&i_status);

			}
	
		}
		printf(" Completed run %d of %d.\n",k+1,num_records);
	}
	
	/* Output the results to a text file. */
	
	/* First, convert t_obs to a more reasonable product. */
	
	for (i=0;i<num_records;i++){			
	
		t_secs[i]=isotime(t_obs_s[i]);

	}

	printf("Writing to file %s.\n",outfile_name);
	
	outptr=fopen(outfile_name,"w");
	bad_outptr=fopen(bad_outfile_name,"w");
	
	fprintf(outptr,"Active Region: %d\n",noaa_ar);
	fprintf(outptr,"Full UT Time            time(s)  num pos  num neg\n");
	fprintf(outptr,"----------------------  -------  -------  -------\n");
	
	fprintf(bad_outptr,"Active Region: AR%d\n",noaa_ar);
	fprintf(bad_outptr,"Full UT Time            quality  time(s)  number\n");
	fprintf(bad_outptr,"----------------------  -------  -------  ------\n");
	
	for (i=0;i<num_records;i++){
		
		/* Make times relative to the first recorded one. */
		
		if (quality[i] == 0){
		
			fprintf(outptr,"%s  %7ld  %6.2lf  %6.2lf\n",t_obs_s[i],t_secs[i]-t_secs[0],p_spots[i],n_spots[i]);
	
		} else {
			
			fprintf(bad_outptr,"%s  0x%08lX  %7ld  %d\n",t_obs_s[i],quality[i],t_secs[i],i+1);
			
		}
	}
	
	fclose(outptr);
	fclose(bad_outptr);
	
	printf("Done!\n");
	
	/* Free memory associated with dynamic arrays. */
    
	free(p_spots);
	free(n_spots);

	free(t_secs);
	free(t_obs_s);
	
	free(quality);
	
	/* Close the drms records connection */
	
	drms_close_records(drms_ids,DRMS_FREE_RECORD);
    
	/* Done! */
    
	return 0;
}
Esempio n. 10
0
void
print_header (struct tar_entry *entry)
{
  char modes[11];
  char *timestamp;
  char uform[11], gform[11];	/* these hold formatted ints */
  char *user, *group;
  char size[24];		/* holds a formatted long or maj, min */
  time_t longie;		/* to make ctime() call portable */
  int pad;
  char *name;

  if (checkpoint_option)
    flush_progress_dots ();

  if (block_number_option)
    fprintf (stdlis, _("block %10lu: "),
	     (unsigned long) current_block_ordinal ());

  if (verbose_option_count <= 1)
    if (null_option)
      {
	fputs (entry->name, stdlis);
	putc ('\0', stdlis);
      }
    else
      {
	char *quoted_name = quote_copy_string (entry->name);

	if (quoted_name)
	  {
	    fputs (quoted_name, stdlis);
	    free (quoted_name);
	  }
	else
	  fputs (entry->name, stdlis);

	putc ('\n', stdlis);
      }
  else
    {
      /* File type and modes.  */

      modes[0] = '?';
      switch (entry->block->header.typeflag)
	{
	case GNUTAR_VOLHDR:
	  modes[0] = 'V';
	  break;

	case GNUTAR_MULTIVOL:
	  modes[0] = 'M';
	  break;

	case GNUTAR_NAMES:
	  modes[0] = 'N';
	  break;

	case GNUTAR_LONGNAME:
	case GNUTAR_LONGLINK:
	  ERROR ((0, 0, _("Long name has no introducing header")));
	  break;

	case GNUTAR_SPARSE:
	case REGTYPE:
	case AREGTYPE:
	case LNKTYPE:
	  modes[0] = '-';
	  if (entry->name[strlen (entry->name) - 1] == '/')
	    modes[0] = 'd';
	  break;
	case GNUTAR_DUMPDIR:
	  modes[0] = 'd';
	  break;
	case DIRTYPE:
	  modes[0] = 'd';
	  break;
	case SYMTYPE:
	  modes[0] = 'l';
	  break;
	case BLKTYPE:
	  modes[0] = 'b';
	  break;
	case CHRTYPE:
	  modes[0] = 'c';
	  break;
	case FIFOTYPE:
	  modes[0] = 'p';
	  break;
	case CONTTYPE:
	  modes[0] = 'C';
	  break;
	}

      decode_mode (entry->stat.st_mode, modes + 1);

      /* Timestamp.  */

      longie = entry->stat.st_mtime;
#if USE_OLD_CTIME
      timestamp = ctime (&longie);
      timestamp[16] = '\0';
      timestamp[24] = '\0';
#else
      timestamp = isotime (&longie);
      timestamp[16] = '\0';
#endif

      /* User and group names.  */

      if (*entry->block->header.uname && entry->format != V7_FORMAT)
	user = entry->block->header.uname;
      else
	{
	  user = uform;
	  sprintf (uform, "%lu",
		   (unsigned long) get_header_uid (entry->block));
	}

      if (*entry->block->header.gname && entry->format != V7_FORMAT)
	group = entry->block->header.gname;
      else
	{
	  group = gform;
	  sprintf (gform, "%ld",
		   (unsigned long) get_header_gid (entry->block));
	}

      /* Format the file size or major/minor device numbers.  */

      switch (entry->block->header.typeflag)
	{
#if defined(S_IFBLK) || defined(S_IFCHR)
	case CHRTYPE:
	case BLKTYPE:
	  sprintf (size, "%lu,%lu",
		   (unsigned long) major (entry->stat.st_rdev),
		   (unsigned long) minor (entry->stat.st_rdev));
	  break;
#endif

	case GNUTAR_SPARSE:
	  sprintf (size, "%lu",
		   (unsigned long) get_header_realsize (entry->block));
	  break;

	default:
	  sprintf (size, "%lu", (unsigned long) entry->stat.st_size);
	}

      /* Figure out padding and print the whole line.  */

      pad = strlen (user) + strlen (group) + strlen (size) + 1;
      if (pad > ugswidth)
	ugswidth = pad;

#if USE_OLD_CTIME
      fprintf (stdlis, "%s %s/%s %*s%s %s %s",
	       modes, user, group, ugswidth - pad, "",
	       size, timestamp + 4, timestamp + 20);
#else
      fprintf (stdlis, "%s %s/%s %*s%s %s",
	       modes, user, group, ugswidth - pad, "", size, timestamp);
#endif

      name = quote_copy_string (entry->name);
      if (name)
	{
	  fprintf (stdlis, " %s", name);
	  free (name);
	}
      else
	fprintf (stdlis, " %s", entry->name);

      switch (entry->block->header.typeflag)
	{
	case SYMTYPE:
	  name = quote_copy_string (entry->linkname);
	  if (name)
	    {
	      fprintf (stdlis, " -> %s\n", name);
	      free (name);
	    }
	  else
	    fprintf (stdlis, " -> %s\n", entry->linkname);
	  break;

	case LNKTYPE:
	  name = quote_copy_string (entry->linkname);
	  if (name)
	    {
	      fprintf (stdlis, _(" link to %s\n"), name);
	      free (name);
	    }
	  else
	    fprintf (stdlis, _(" link to %s\n"), entry->linkname);
	  break;

	default:
	  fprintf (stdlis, _(" unknown file type `%c'\n"),
		   entry->block->header.typeflag);
	  break;

	case AREGTYPE:
	case REGTYPE:
	case GNUTAR_SPARSE:
	case CHRTYPE:
	case BLKTYPE:
	case DIRTYPE:
	case FIFOTYPE:
	case CONTTYPE:
	case GNUTAR_DUMPDIR:
	  putc ('\n', stdlis);
	  break;

	case GNUTAR_VOLHDR:
	  fprintf (stdlis, _("--Volume Header--\n"));
	  break;

	case GNUTAR_MULTIVOL:
	  fprintf (stdlis, _("--Continued at byte %lu--\n"),
		   (unsigned long) get_header_offset (entry->block));
	  break;

	case GNUTAR_NAMES:
	  fprintf (stdlis, _("--Mangled file names--\n"));
	  break;
	}
    }
  fflush (stdlis);
}
Esempio n. 11
0
int DoIt(){
 
    /* Variable declarations */

    /* Generic use variables */

    int i,j,k,l,n;								/* Generic loop counters */

    /* DRMS/JSOC variables */

	char *harpnum,*time_range;					/* SHARPs ID and time range from module_args[] */
	double umb_sig, pen_sig;					/* Cutoffs for sunspots */
	int num_divs;								/* Number of divisions to break a data strip into for trend removal */
	char *drms_query;							/* The DRMS query we are going to send */
	int num_query_chars;						/* Number of characters in total query for malloc definition */
	CmdParams_t *params=&cmdparams;				/* For the module_args stuff */
	DRMS_RecordSet_t *drms_ids;					/* Holds the id structure of the records */
	DRMS_Record_t *drms_record;					/* Holds specific record information */
	DRMS_Segment_t *drms_segment;				/* Segment information */
	int drms_status;							/* Status variable */
	int num_records;							/* Number of records and variables to get the segment locations we need */
	
	/* cfitsio-related variables */

    fitsfile *v_ptr,*i_ptr,*c_ptr;		/* Pointers for FITS files */
    fitsfile *info_ptr;		
    int v_status,i_status,c_status;		/* Status checker for opening files */
    int info_status;					
    int hdu_pos,num_hdus;				/* HDU number and location */
    int needed_hdu;						/* The HDU we want to be on */
    int any_nulls;						/* Nonzero if there are null values in data */
    char i_filename[DRMS_MAXPATHLEN+1],v_filename[DRMS_MAXPATHLEN+1];		/* Containers for the filenames */
	char c_filename[DRMS_MAXPATHLEN+1],info_filename[DRMS_MAXPATHLEN+1];
	double nulval;							/* Container for what null values in data should be set to */
	long l_nulval;

    /* Needed FITS keywords */

    int naxis1,naxis2,naxis;			/* Length of axes */
    double crpix1,crpix2;				/* SHARPs CRPIX is the center of the Sun relative to the lower left of the patch (fortranL 1,1) */
    double imcrpix1,imcrpix2;			/* SHARPs IMCRPIX is the center of the Sun in full plate coordinates (fortran) */
    double cdelt1,cdelt2;				/* HMI pixel sizes in as */    double blank;						/* Values of bad data */
    double crota2,crln_obs,crlt_obs;	/* Rotation, carrington observer location */
    double dsun_obs,rsun_obs;			/* Distance to and radius of the sun, observed at t_obs */
    double obs_vr,obs_vw,obs_vn;		/* Satellite velocity keywords */
    TIME t_obs;							/* Observation time, ZULU */
    char **t_obs_s;						/* String version of observation time */
    long *quality;						/* Data quality keyword */
    
    /* Data-related variables */
    
    double **vlos_dat, **inc_dat;			/* Data arrays, size defined once naxis1/2 are known */
    double **con_dat;
    long **info_dat;
    double *v_pixel_strip;					/* Strip of pixels read from the field data */
    double *i_pixel_strip;					/* Strip of pixels read from the inclination data */
    double *c_pixel_strip;					/* Strip of pixels read from the continuum data */
    long *info_pixel_strip;					/* Strip of pixels read from the continuum data */
    long fpixel[2];							/* Holds the location of pixel to be read */
    LONGLONG nelements;						/* Number of elements in a strip to be read (naxis2) */
    FILE *outptr,*bad_outptr;				/* Pointer to the outfile */
    char outfile_name[25];					/* Name of the outfile */
    char bad_outfile_name[24];				/* Name of the outfile for bad quality*/
    
    /* Variables related to the actual task */
    
    double rscx,rscy;				/* Disk center, plate coordinates */
    double rllx,rlly;				/* Disk center, patch coordinates */
    double rpllx,rplly;				/* Lower left of patch, plate coordinates */
    double **radius;				/* Array to hold where the Sun's boundaries are, column major order */
	double umb,pen;					/* Intensity cutoffs for the umbra and penumbra */
    double num_good;				/* The number of nonzero continuum values in a sunspot region */
    double mu;						/* Angle from solar center */
    double rsun_pix,xx,yy,r;		/* Variables associated with radial boundaries */
    long *t_secs;					/* T_OBS time converted to seconds since UNIX epoch */
    double *umb_p_vel,*umb_n_vel;	/* Umbral LOS velocities */
    double *pen_p_vel,*pen_n_vel;	/* Penumbral LOS velocities */
    double umb_p_counter,umb_n_counter;	/* Counters for averages */
    double pen_p_counter,pen_n_counter;
    double vr,vn,vw,vt;				/* Various LOS velocities due to satellite motion and solar rotation */
    double vlos;					/* VLOS after removing all of the satellite motion and solar rotation */
    double **y_axis;				/* Array to be looped over wrt naxis2 to remove trends */
    double **y_error;				/* Error on y axis, taken as 1 */
    double **x_axis;				/* Array to be looped over that holds naxis1 information for fitting */
    double x,y;						/* Pixel location on the solar disk */
    double ttx,tty,tx,ty,zz;		/* Intermediate variables for coordinate conversions */
    double lat,lon;					/* Carrington coordinate latitude and longitude */
    double p,t;						/* Spherical phi and theta coordinates */
	int noaa_ar;					/* Active region number */
	mp_result result;				/* Fitting result structure */
	mp_config config;				/* Configuration options for fitting structure */
	double perror[2];				/* Error on fitting coefficients */
	double fit_params[2];			/* Fitting coefficients */
	struct vars_struct v;			/* Private data, shared between main and functions */
	int fit_status;					/* Fitting returned status */
	int inv_len;					/* Interval length for breaking data up */
	
       
    /* Initialise variables that need it */

    drms_status=0;
    
	memset(&result,0,sizeof(result));
	memset(&config,0,sizeof(config));
	
	/* Set the error stuff for cmfit */
	
	result.xerror=perror;
	
	/* Set the default options for cmfit */
	
	config.ftol=1.49012e-08;
	config.xtol=1.49012e-08;
	config.gtol=0.0;
	config.maxfev=0;
    
	/* Grab values from module_args[] */

	harpnum=strdup(params_get_str(params,"harpnum"));
	time_range=strdup(params_get_str(params,"time_range"));
	umb_sig=params_get_double(params,"umb_sig");
	pen_sig=params_get_double(params,"pen_sig");
	num_divs=params_get_int(params,"num_divs");
	
	/* Now we start the main program. The rough layout is as follows: 
	   
	   1. Query drms. Based on what we learn, either exit or grab what we need from it.
	   2. Loop through the files, calculate field stuff.
	   3. Print out a table of values at the end.				   */
	
	/* Forge the DRMS query. */
	
	num_query_chars=16+strlen(harpnum);		/* hmi.sharp_720s[] is 16 characters */
	
	if (time_range!="[]"){
		
		num_query_chars+=strlen(time_range);
		
	}
	
	drms_query=calloc(num_query_chars,sizeof(char));
	strcat(drms_query,"hmi.sharp_720s[");
	strcat(drms_query,harpnum);
	strcat(drms_query,"]");
	
	if (time_range!="[]"){
	
		strcat(drms_query,time_range);
		
	}
	
	/* Query DRMS for the records. */
	
	printf("Querying DRMS. This may take some time.\n");
	
	if (!(drms_ids=drms_open_records(drms_env,drms_query,&drms_status))){
		
		printf("No record sets match your criteria. Check your SHARPs ID and your time range.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		free(drms_query);
		return 0;
		
	}

	free(drms_query);

	num_records=drms_ids->n;
	printf("%d records match. Checking to make sure we have the needed data segments.\n",num_records);

	drms_record=drms_ids->records[0];

	if (!(drms_segment_lookup(drms_record,"vlos_mag"))){
		
		printf("vlos_mag segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}

	if (!(drms_segment_lookup(drms_record,"inclination"))){
		
		printf("Inclination segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}

	if (!(drms_segment_lookup(drms_record,"continuum"))){
		
		printf("Continuum segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}

	if (!(drms_segment_lookup(drms_record,"info_map"))){
		
		printf("Info_map segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;

	}

	/* Now we can start. We loop over all records, get the keyword information we need, get the data, and then calculate. */
	
	/* First set the size of some of the pointers that are intended to be arrays. */
	
	/* Time-related arrays */
	
	t_secs=malloc(num_records*sizeof(long));
	t_obs_s=malloc(num_records*sizeof(char *));
	
	for (i=0;i<num_records;i++){
		
		t_obs_s[i]=malloc(T_OBS_LENGTH*sizeof(char));
		
	}
	
	/* Data-related arrays */
	
	umb_p_vel=malloc(num_records*sizeof(double));
	pen_p_vel=malloc(num_records*sizeof(double));
	umb_n_vel=malloc(num_records*sizeof(double));
	pen_n_vel=malloc(num_records*sizeof(double));

	/* Record quality */
	
	quality=malloc(num_records*sizeof(long));
	
	for (k=0;k<num_records;k++){ 

		drms_record=drms_ids->records[k];
		
		/* Check to see if we have data for a particular observation time */
		
		if (!(t_obs=drms_getkey_time(drms_record,"T_OBS",&drms_status))){
					
			printf("Keyword %s not present! Exiting.\n","T_OBS");
			drms_close_records(drms_ids,DRMS_FREE_RECORD);
			return 0;
		
		}
		
		if (time_is_invalid(t_obs)){
			
			printf("Bad record, skipping.\n");
			
		} else {
			
			if (k == 0){
				
				/* Get active region number for pregame info */
			
				if (!(noaa_ar=drms_getkey_int(drms_record,"NOAA_AR",&drms_status))){
					
					printf("Keyword %s not present! Exiting.\n","NOAA_AR");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
		
				}
				
				/* Create data output filename */
			
				sprintf(outfile_name,"AR%d.fvlos-output.dat",noaa_ar);
				sprintf(bad_outfile_name,"AR%d.bad-quality.dat",noaa_ar);
							
				/* Print out some stats before we run */
			
				printf("Pre-analysis details:\n");
				printf("Analyzing: HARP Number: %s\t NOAA AR: %d\n",harpnum,noaa_ar);
				printf("Output file: %s\n",outfile_name);
			
				if (time_range == "[]\0"){
				
					printf("We are covering the entire data set.\n");
			
				} else {
				
					printf("Time range: %s\n",time_range);
			
				}

				printf("\n\n");	
			}
			
			printf("Processing record %d of %d.\n",k+1,num_records);
		
			/* Fill keywords */
			
			if (!(quality[k]=drms_getkey_longlong(drms_record,"QUALITY",&drms_status))){
			
				quality[k]=0;
		
			}
	
			if (!(crpix1=drms_getkey_double(drms_record,"CRPIX1",&drms_status))){
			
				printf("Keyword %s not present! Exiting.\n","CRPIX1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(crpix2=drms_getkey_double(drms_record,"CRPIX2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CRPIX2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
		
			if (!(cdelt1=drms_getkey_double(drms_record,"CDELT1",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CDELT1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(cdelt2=drms_getkey_double(drms_record,"CDELT2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CDELT2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(imcrpix1=drms_getkey_double(drms_record,"IMCRPIX1",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","IMCRPIX1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(imcrpix2=drms_getkey_double(drms_record,"IMCRPIX2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","IMCRPIX2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(rsun_obs=drms_getkey_double(drms_record,"RSUN_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","RSUN_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}

			if (!(dsun_obs=drms_getkey_double(drms_record,"DSUN_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","DSUN_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(obs_vr=drms_getkey_double(drms_record,"OBS_VR",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","OBS_VR");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}

			if (!(obs_vn=drms_getkey_double(drms_record,"OBS_VN",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","OBS_VN");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(obs_vw=drms_getkey_double(drms_record,"OBS_VW",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","OBS_VW");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}

			if (!(crota2=drms_getkey_double(drms_record,"CROTA2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CROTA2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(crln_obs=drms_getkey_double(drms_record,"CRLN_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CRLN_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(crlt_obs=drms_getkey_double(drms_record,"CRLT_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CRLT_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}

			if (!(blank=drms_getkey_double(drms_record,"BLANK",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","BLANK");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			sprint_ut(t_obs_s[k],t_obs);		/* Convert to string */
		
			printf(" Checking quality.\n");
			
			if (quality[k] == 0){
		
				/* Ok, now we get the file locations for the data from DRMS. Originally I attempted
				* to pull the data directly from DRMS but there were vague free() and malloc() issues
				* possibly due to icc and multithreading, or library problems. */
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"vlos_mag"))){
			
					printf("Problem opening the vlos_mag segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,v_filename);
			
				if (!(drms_segment=drms_segment_lookup(drms_record,"continuum"))){
				
					printf("Problem opening the continuum segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,c_filename);
			
				/* naxis1 and naxis2 we get from segment information */
		
				naxis1=(int)drms_segment->axis[0];
				naxis2=(int)drms_segment->axis[1];
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"inclination"))){
			
					printf("Problem opening the inclination segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,i_filename);
			
				if (!(drms_segment=drms_segment_lookup(drms_record,"info_map"))){
			
					printf("Problem opening the info_map segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
			
				drms_segment_filename(drms_segment,info_filename);
			
				printf(" Opening FITs files.\n");
		
				/* Now open the FITS files and get to work. */
	
				v_status=0;
				i_status=0;
				c_status=0;
				info_status=0;
				any_nulls=0;

				if (fits_open_file(&v_ptr,v_filename,READONLY,&v_status)){
				
					printf("Cannot open %s! Exiting.\n",v_filename);
					exit(0);

				}

				if (fits_open_file(&i_ptr,i_filename,READONLY,&i_status)){
				
					printf("Cannot open %s! Exiting.\n",i_filename);
					fits_close_file(i_ptr,&i_status);
					exit(0);

				}
			
				if (fits_open_file(&c_ptr,c_filename,READONLY,&c_status)){
				
					printf("Cannot open %s! Exiting.\n",c_filename);
					fits_close_file(c_ptr,&c_status);
					exit(0);

				}
			
				if (fits_open_file(&info_ptr,info_filename,READONLY,&info_status)){
				
					printf("Cannot open %s! Exiting.\n",info_filename);
					fits_close_file(info_ptr,&info_status);
					exit(0);

				}
				
				
				/* Walk through the HDUs until we get to one with NAXIS=2 */

				/* Number of headers and which one we are on */

				fits_get_num_hdus(v_ptr,&num_hdus,&v_status);
				fits_get_hdu_num(v_ptr,&hdu_pos);

				/* Find the one with two naxes */

				naxis=0;

				for (i=1;i<=num_hdus;i++){
				
					fits_movabs_hdu(v_ptr,i,NULL,&v_status);
					fits_read_key(v_ptr,TINT,"NAXIS",&naxis,NULL,&v_status);
				
					if (naxis == 2){
	
						needed_hdu=i;
	
					}
				}


				/* Set all to the needed HDU */

				if (naxis == 0){
		
					printf("HDU problems: can't find one with the required number of axes.\n");
					fits_close_file(v_ptr,&v_status);
					fits_close_file(i_ptr,&i_status);
					fits_close_file(c_ptr,&c_status);
					fits_close_file(info_ptr,&info_status);
					exit(0);

				} else {

					fits_movabs_hdu(v_ptr,needed_hdu,NULL,&v_status);
					fits_movabs_hdu(i_ptr,needed_hdu,NULL,&i_status);
					fits_movabs_hdu(c_ptr,needed_hdu,NULL,&c_status);
					fits_movabs_hdu(info_ptr,needed_hdu,NULL,&info_status);

				}


				/* Now set some definite boundaries on arrays to help with memory usage. Arrays are called as con_dat[y][x]. */
				
				inv_len=naxis1/num_divs;
				
				vlos_dat=malloc(naxis2*sizeof(double *));
				inc_dat=malloc(naxis2*sizeof(double *));
				con_dat=malloc(naxis2*sizeof(double *));
				radius=malloc(naxis2*sizeof(double *));
				info_dat=malloc(naxis2*sizeof(long *));
				y_axis=malloc(num_divs*sizeof(double *));
				y_error=malloc(num_divs*sizeof(double *));
				x_axis=malloc(num_divs*sizeof(double *));
			
				v_pixel_strip=calloc(naxis1,sizeof(double));
				i_pixel_strip=calloc(naxis1,sizeof(double));
				c_pixel_strip=calloc(naxis1,sizeof(double));
				info_pixel_strip=calloc(naxis1,sizeof(long));
	
				for (j=0;j<naxis2;j++){
		
					vlos_dat[j]=calloc(naxis1,sizeof(double));
					inc_dat[j]=calloc(naxis1,sizeof(double));
					con_dat[j]=calloc(naxis1,sizeof(double));
					radius[j]=calloc(naxis1,sizeof(double));
					info_dat[j]=calloc(naxis1,sizeof(long));
		
				}
				
				for (j=0;j<(num_divs-1);j++){
					
					x_axis[j]=calloc((inv_len),sizeof(double));
					y_axis[j]=calloc((inv_len),sizeof(double));
					y_error[j]=calloc((inv_len),sizeof(double));
					
				}
				
				x_axis[num_divs-1]=calloc((inv_len + naxis1%num_divs),sizeof(double));
				y_axis[num_divs-1]=calloc((inv_len + naxis1%num_divs),sizeof(double));
				y_error[num_divs-1]=calloc((inv_len + naxis1%num_divs),sizeof(double));
				
				/* Next, put data in the arrays, clear out blank values and NaNs from the data */
	
				fpixel[0]=1;		/* cfitsio uses fortran reference instead of c when accessing data */
				nelements=naxis1;
				nulval=0;
				l_nulval=0;
				any_nulls=0;
    
				for (j=0;j<naxis2;j++){
		
					fpixel[1]=j+1;	/* Add 1 to account for fortran FITS indexing */
					fits_read_pix(v_ptr,TDOUBLE,fpixel,nelements,&nulval,v_pixel_strip,&any_nulls,&v_status);
					fits_read_pix(i_ptr,TDOUBLE,fpixel,nelements,&nulval,i_pixel_strip,&any_nulls,&i_status);
					fits_read_pix(c_ptr,TDOUBLE,fpixel,nelements,&nulval,c_pixel_strip,&any_nulls,&c_status);
					fits_read_pix(info_ptr,TLONG,fpixel,nelements,&l_nulval,info_pixel_strip,&any_nulls,&info_status);
		
					for (i=0;i<naxis1;i++){
			
						/* Kill blank values if present, if not assign to the correct place in array */
			
						if (v_pixel_strip[i] == blank){
				
							vlos_dat[j][i]=0.0;
					
						} else {
				
							vlos_dat[j][i]=v_pixel_strip[i];
			
						}
			
						if (i_pixel_strip[i] == blank){
				
							inc_dat[j][i]=0.0;
				
						} else {
					
							inc_dat[j][i]=i_pixel_strip[i];
			
						}

						if (c_pixel_strip[i] == blank){
				
							con_dat[j][i]=0.0;
			
						} else {
					
							con_dat[j][i]=c_pixel_strip[i];
			
						}
					
						info_dat[j][i]=info_pixel_strip[i];
					
					}
				}
				
		
				printf(" Analyzing data.\n");
	
				/* Coordinate variable definitions for future use. See the declaration section */
				/* at the front of the code to understand what these refer to. */
	
				rscx=(imcrpix1-1.0);
				rscy=(imcrpix2-1.0);
				rllx=(crpix1-1.0);
				rlly=(crpix2-1.0);
				rpllx=(rscx-rllx);
				rplly=(rscy-rlly);
	
				/* Fill the radius array, handle limb darkening */
	
				rsun_pix=rsun_obs/cdelt1;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
			
						xx=(double)i-rllx;
						yy=(double)j-rlly;
						r=sqrt(xx*xx+yy*yy);
				
						if (r <= rsun_pix){
				
							radius[j][i]=r;
							mu=sqrt(1-pow(r/rsun_pix,2.0));
							con_dat[j][i]=con_dat[j][i]/limb_darken(mu);
					
						}
					}
				}
			
				/* Determine if we actually have an active region here. */
			
				spotbounds(con_dat,naxis1,naxis2,&umb,&pen,umb_sig,pen_sig);
			
				num_good=0;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
		
						if ((radius[j][i] > 0)&&(con_dat[j][i] <= pen)&&(con_dat[j][i] > 0)){
				
							num_good++;
			
						}
					}
				}
	
				/* Now find the average LOS velocities. */
			
				umb_p_vel[k]=0;
				pen_p_vel[k]=0;
				umb_n_vel[k]=0;
				pen_n_vel[k]=0;
				
				umb_p_counter=0.0;
				umb_n_counter=0.0;
				pen_p_counter=0.0;
				pen_n_counter=0.0;
			
				if (num_good > 0){
					
					/* We're going to do these loops twice - first to remove any satellite and differential 
					 * rotation effects, then again to fit and remove trends. */
			
					/* First the satellite motion and the differential rotation */
			
					for (i=0;i<naxis1;i++){
				
						for (j=0;j<naxis2;j++){
							
							if ((radius[j][i] > 0)&&(good_pixel(info_dat[j][i]))){
								
								/* Get the pixel location in HPL coordinates */
							
								x=rpllx+(double)i;
								y=rplly+(double)j;
								
								/* Stonyhurst/carrington needed for photospheric velocity calcs */
							
								pixel2hpl(x,y,crota2,imcrpix1,imcrpix2,cdelt1,cdelt2,&tx,&ty);	
								hpl2stony(tx,ty,dsun_obs,crln_obs,crlt_obs,&lat,&lon);
								
								/* Photospheric rotation removal */
								
								vt=v_t(lat,0,0,0)*along_phi(t,p,dsun_obs); /*0's are for default coefficients */
							
								/* Convert to spherical with no rotation to account for sat orientation and handle LOS stuff */
							
								pixel2hpl(x,y,0.0,imcrpix1,imcrpix2,cdelt1,cdelt2,&tx,&ty);
								hpl2hpc(tx,ty,&ttx,&tty);
								hpc2hcc(ttx,tty,dsun_obs,&xx,&yy,&zz);
								hcc2sphere(xx,yy,zz,&t,&p);
							
								/* LOS satellite velocity components */
							
								vr=obs_vr*along_obs(t,p,dsun_obs);
								vn=obs_vn*along_north(t,p,dsun_obs);
								vw=obs_vw*along_west(t,p,dsun_obs);
								
								/* vlos after removing all of the doppler effects. The 
								 * division by 100 is to convert cm/s to m/s. */
								
								vlos_dat[j][i]=(vlos_dat[j][i]/100)-vr-vn-vw-vt;
								
							}
						}
					}
					
					/* Next we fit a function across x, not including points that would be in a sunspot or off-disk points.
					 * Then we subtract this trend from the remaining data. */
					 
					for (j=0;j<naxis2;j++){
				
						/* Fill the arrays along x */
				
						for (i=0;i<num_divs;i++){
							
							if (i < (num_divs-1)){
								
								/* There are a total of num_divs segments in a data strip.
								 * To handle remainders when determining how many points to 
								 * place in a segment, we first do the remainderless ones.
								 * The last may or may not have a remainder, but that's where
								 * one would go if it did, so we do it separately. */
							
								for (l=0;l<inv_len;l++){
									
									n=i*inv_len+l;
									y_error[i][l]=1;
									x_axis[i][l]=(double)n;
									
							
									if ((radius[j][n] > 0)&&(con_dat[j][n] > pen)&&(good_pixel(info_dat[j][n]))){
								
										y_axis[i][l]=vlos_dat[j][n];
								
									} else {
								
										y_axis[i][l]=0.0;
								
									}
						
								}
								
							} else {
								
								/* Handle the one that might have a remainder */
								
								for (l=0;l<(inv_len + naxis1%num_divs);l++){
									
									n=(num_divs-1)*inv_len+l;
									y_error[num_divs-1][l]=1;
									x_axis[num_divs-1][l]=(double)n;
									
							
									if ((radius[j][n] > 0)&&(con_dat[j][n] > pen)&&(good_pixel(info_dat[j][n]))){
								
										y_axis[num_divs-1][l]=vlos_dat[j][n];
								
									} else {
								
										y_axis[num_divs-1][l]=0.0;
								
									}
						
								}
								
							}
							
						}
						
						/* Now we fit, but in strips determined by num_divs */
						
						for (i=0;i<num_divs;i++){
							
							if (i < (num_divs-1)){
									
								v.x=x_axis[i];
								v.y=y_axis[i];
								v.ey=y_error[i];
	
								fit_status=mpfit(fit_me,inv_len,2,fit_params,0,&config,(void *)&v,&result);
								
								for (l=0;l<inv_len;l++){
									
									n=i*inv_len+l;
									vlos_dat[j][n]=vlos_dat[j][n]-(fit_params[0]*x_axis[i][l]+fit_params[1]);	/* Subtract trend */
									
								}
								
							} else {
								
								v.x=x_axis[num_divs-1];
								v.y=y_axis[num_divs-1];
								v.ey=y_error[num_divs-1];
	
								fit_status=mpfit(fit_me,inv_len + naxis1%num_divs,2,fit_params,0,&config,(void *)&v,&result);
							
								for (l=0;l<(inv_len + naxis1%num_divs);l++){
									
									n=(num_divs-1)*inv_len+l;
									vlos_dat[j][n]=vlos_dat[j][n]-(fit_params[0]*x_axis[num_divs-1][l]+fit_params[1]);	/* Subtract trend */
									
								}
								
							}
						}	
								
					}
					
					/* Finally, we have a clean data set. Now get to work on it. */
					 
					 
					for (i=0;i<naxis1;i++){
				
						for (j=0;j<naxis2;j++){
							
							if ((radius[j][i] > 0)&&(con_dat[j][i] < pen)&&(good_pixel(info_dat[j][i]))){
						
								/* "Positive" sunspot polarities. */
								
								vlos=vlos_dat[j][i];
							
								if (inc_dat[j][i] < 90){
								
									if (con_dat[j][i] <= umb){
									
										umb_p_vel[k]+=vlos;
										umb_p_counter++;
								
									}
								
									if (con_dat[j][i] > umb){
									
										pen_p_vel[k]+=vlos;
										pen_p_counter++;
									
									}
								
					
								}
					
								/* "Negative" sunspot polarities. */
					
								if (inc_dat[j][i] > 90){
							
								
									if (con_dat[j][i] <= umb){
									
										umb_n_vel[k]+=vlos;
										umb_n_counter++;
								
									}
								
									if (con_dat[j][i] > umb){
									
										pen_n_vel[k]+=vlos;
										pen_n_counter++;
									
									}
					
								}
							
							}
						}
					}
				
				}
				
				if (umb_p_counter > 0){
					
					umb_p_vel[k]/=umb_p_counter;
					
				} else {
					
					umb_p_vel[k]=0;
					
				}
			
				if (umb_n_counter > 0){
					
					umb_n_vel[k]/=umb_n_counter;
					
				} else {
					
					umb_n_vel[k]=0;
					
				}
				
				if (pen_p_counter > 0){
					
					pen_p_vel[k]/=pen_p_counter;
					
				} else {
					
					pen_p_vel[k]=0;
					
				}

				if (pen_n_counter > 0){
					
					pen_n_vel[k]/=pen_n_counter;
					
				} else {
					
					pen_n_vel[k]=0;
					
				}
				
			
				/* Free up dynamic arrays and close the files for the next iteration. */
				
				for (i=0;i<naxis2;i++){
				
					free(vlos_dat[i]);
					free(inc_dat[i]);
					free(con_dat[i]);
					free(radius[i]);
					free(info_dat[i]);
					
				}
				
				free(vlos_dat);
				free(inc_dat);
				free(con_dat);
				free(radius);
				free(info_dat);
				
				
				free(v_pixel_strip);
				free(i_pixel_strip);
				free(c_pixel_strip);
				free(info_pixel_strip);
				
				free(x_axis);
				free(y_axis);
				free(y_error);
			
				fits_close_file(v_ptr,&v_status);
				fits_close_file(i_ptr,&i_status);
				fits_close_file(c_ptr,&c_status);
				fits_close_file(info_ptr,&info_status);

			}
	
		}
	
		printf(" Completed run %d of %d.\n",k+1,num_records);
		
	}
	
	/* Output the results to a text file. */
	
	/* First, convert t_obs to a more reasonable product. */
	
	for (i=0;i<num_records;i++){			
	
		t_secs[i]=isotime(t_obs_s[i]);

	}

	printf("Writing to file %s.\n",outfile_name);
	
	outptr=fopen(outfile_name,"w");
	bad_outptr=fopen(bad_outfile_name,"w");
	
	fprintf(outptr,"Active Region: %d\tVelocities are in m/s, fvlos is scaled to remove limb effects.\n",noaa_ar);
	fprintf(outptr,"Full UT Time            time(s)  vlos pumb  vlos ppen  vlos numb  vlos npen\n");
	fprintf(outptr,"----------------------  -------  ---------  ---------  ---------  ---------\n");

	fprintf(bad_outptr,"Active Region: AR%d\n",noaa_ar);
	fprintf(bad_outptr,"Full UT Time            quality  time(s)  number\n");
	fprintf(bad_outptr,"----------------------  -------  -------  ------\n");
	
	for (i=0;i<num_records;i++){
		
		/* Make times relative to the first recorded one. */
		
		if (quality[i] == 0){
		
			fprintf(outptr,"%s  %7ld  %6.2lf  %6.2lf  %6.2lf  %6.2lf\n",t_obs_s[i],t_secs[i]-t_secs[0],umb_p_vel[i],pen_p_vel[i],umb_n_vel[i],pen_n_vel[i]);
		
		} else {
			
			fprintf(bad_outptr,"%s  0x%08lX  %7ld  %d\n",t_obs_s[i],quality[i],t_secs[i],i+1);		
		
		}

	}
	
	fclose(outptr);
	fclose(bad_outptr);
	
	printf("Done!\n");
	
	/* Free memory associated with dynamic arrays. */

	free(t_secs);
	free(t_obs_s);
	
	free(umb_p_vel);
	free(pen_p_vel);
	free(umb_n_vel);
	free(pen_n_vel);
	
	free(quality);
	
	
	/* Close the drms records connection */
	
	drms_close_records(drms_ids,DRMS_FREE_RECORD);
    
	/* Done! */
    
	return 0;
}