#include "isf_bul.h" /* Writes the data type line at the top of a GSE report. Format is: DATA_TYPE data_type:subtype data_format:subformat Only data_type is required. Only other limitation is that a subformat is not allowed without a data_format. This is the only write routine that does not check the value of 'isf_prev_line_type' - this is the first line of a new report. Returns 0 on a successful write. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_data_type(FILE *fp, char *data_type, char *subtype, char *data_format,char *subformat) { char line_type[] = "data_type"; int len = 10; /* line length so far ('DATA_TYPE ') */ /* Check and write data_type. */ if (data_type[0] == '\0'){ sprintf (isf_bulletin_error,"null data_type given\n"); return 20; } if (check_whole(data_type)){ sprintf (isf_bulletin_error,"bad data_type: %s\n",data_type); return 20; } if (len =+ strlen(data_type) > ISF_LINE_LEN ){ sprintf (isf_bulletin_error,"line too long: %s\n",data_type); return 20; } fprintf(fp,"DATA_TYPE %s",data_type); /* Check and write subtype - if there is one. */ if (subtype[0] != '\0'){ if (len =+ strlen(subtype) > ISF_LINE_LEN ){ sprintf (isf_bulletin_error,"line too long: %s\n",subtype); return 20; } if (check_whole(subtype)){ sprintf (isf_bulletin_error,"bad subtype: %s\n",subtype); return 20; } fprintf(fp,":%s",subtype); } /* Check and write data_format - if there is one. */ if (data_format[0] != '\0'){ if (len =+ strlen(data_format) > ISF_LINE_LEN ){ sprintf (isf_bulletin_error,"line too long: %s\n",data_format); return 20; } if (check_whole(data_format)){ sprintf (isf_bulletin_error,"bad data_format: %s\n",data_format); return 20; } fprintf(fp," %s",data_format); /* Check and write subformat - if there is one. */ if (subformat[0] != '\0'){ if (len =+ strlen(subformat) > ISF_LINE_LEN ){ sprintf(isf_bulletin_error,"line too long:%s\n",subformat); return 20; } if (check_whole(subformat)){ sprintf (isf_bulletin_error,"bad subformat: %s\n",subformat); return 20; } fprintf(fp,":%s",subformat); } } else if (subformat[0] != '\0'){ sprintf (isf_bulletin_error,"subformat given without format\n"); return 20; } fprintf(fp,"\n"); /* Set 'isf_prev_line_type' for future calls to check_prev_line_type. */ /* Do no actual checking for this line_type. */ check_prev_line_type(line_type); return 0; } /* Writes an event title line with a preceding blank line. Requires event ID but will write a line without a region if required. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_event_id(FILE *fp, char *evid, char *region) { char line_type[] = "event_id"; /* Chars 1-5: the word 'Event'. Chars 7-14: event ID. */ if (evid[0] == '\0'){ sprintf (isf_bulletin_error,"missing evid\n"); return 20; } if (strlen(evid) > ISF_EVID_LEN){ sprintf (isf_bulletin_error,"evid too long: %s\n",evid); return 20; } if (check_whole(evid)){ sprintf (isf_bulletin_error,"bad evid: %s\n",evid); return 20; } fprintf(fp,"\nEvent %-*s",ISF_EVID_LEN,evid); /* Chars 16-80: geographic region if given. */ if (region[0] != '\0'){ if (strlen(region) > ISF_REGION_LEN){ sprintf (isf_bulletin_error,"region too long: %s\n",region); return 20; } fprintf(fp," %-s",region); } fprintf(fp,"\n"); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes an origin header line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_origin_head(FILE *fp){ char line_type[] = "origin_head"; char head[] = " Date Time Err RMS Latitude Longitude Smaj Smin Az Depth Err Ndef Nsta Gap mdist Mdist Qual Author OrigID"; fprintf(fp,"%s\n",head); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes an origin line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_origin( FILE *fp, int yyyy, int mm, int dd, int hh, int mi, int ss, int msec, char timfix, float stime, float sdobs, float lat, float lon, char epifix, float smaj, float smin, int strike, float depth, char depfix, float sdepth, int ndef, int nsta, int gap, float mindist, float maxdist, char antype, char loctype, char *etype, char *author, char *origid) { char line_type[] = "origin"; int i; /* Chars 1-10: date. Char 11: space. */ if (is_null(yyyy)){ sprintf (isf_bulletin_error,"missing year\n"); return 20; } if ( yyyy < 1000 || yyyy > 9999 ){ sprintf (isf_bulletin_error,"bad year: %d\n",yyyy); return 20; } if (is_null(mm)){ sprintf (isf_bulletin_error,"missing month\n"); return 20; } if ( mm < 1 || mm > 12 ){ sprintf (isf_bulletin_error,"bad month: %d\n",mm); return 20; } if (is_null(dd)){ sprintf (isf_bulletin_error,"missing day\n"); return 20; } if ( dd < 1 || dd > 31 ){ sprintf (isf_bulletin_error,"bad day: %d\n",dd); return 20; } fprintf (fp,"%04d/%02d/%02d ",yyyy,mm,dd); /* Chars 12-19: time. */ if (is_null(hh)){ sprintf (isf_bulletin_error,"missing hour\n"); return 20; } if ( hh < 0 || hh > 23 ){ sprintf (isf_bulletin_error,"bad hour: %d\n",hh); return 20; } if (is_null(mi)){ sprintf (isf_bulletin_error,"missing minute\n"); return 20; } if ( mi < 0 || mi > 59 ){ sprintf (isf_bulletin_error,"bad minute: %d\n",mi); return 20; } if (is_null(ss)){ sprintf (isf_bulletin_error,"missing second\n"); return 20; } if ( ss < 0 || ss > 59 ){ sprintf (isf_bulletin_error,"bad second: %d\n",ss); return 20; } fprintf (fp,"%02d:%02d:%02d",hh,mi,ss); /* Chars 20-22 msec - put blanks here if no msec provided. */ if (is_null(msec)){ fprintf (fp," "); } else { if ( msec < 0 || msec > 999 ){ sprintf (isf_bulletin_error,"bad msec: %d\n",msec); return 20; } fprintf (fp,".%02d",msec/10); } /* Char 23: fixed time flag. Char 24: space */ if (timfix != ' ' && timfix != 'f'){ sprintf (isf_bulletin_error,"bad timfix: %c\n",timfix); return 20; } fprintf (fp,"%c ",timfix); /* Chars 25-29: optional origin time error. Char 30: space. */ /* printf gives at least 2 decimal places but less if number > 99. */ if (is_null(stime)){ fprintf (fp," "); } else{ if ( stime < 0 || stime > 99999 ){ sprintf (isf_bulletin_error,"bad stime: %f\n",stime); return 20; } print_float(fp,stime,5,2); fprintf(fp," "); } /* Chars 31-35: optional rms (sdobs). Char 36: space. */ /* printf gives at least 2 decimal places but less if number > 99. */ if (is_null(sdobs)){ fprintf (fp," "); } else{ if ( sdobs < 0 || sdobs > 99999 ){ sprintf (isf_bulletin_error,"bad sdobs: %f\n",sdobs); return 20; } print_float(fp,sdobs,5,2); fprintf(fp," "); } /* Chars 37-44: lattitude. Char 45: space. */ if (is_null(lat)){ sprintf (isf_bulletin_error,"missing latitude\n"); return 20; } if ( lat <= -90 || lat > 90 ){ sprintf (isf_bulletin_error,"bad lat: %f\n",lat); return 20; } fprintf (fp,"%8.4f ",lat); /* Chars 46-54: longitude. */ if (is_null(lon)){ sprintf (isf_bulletin_error,"missing longitude\n"); return 20; } if ( lon < -180 || lon > 180 ){ sprintf (isf_bulletin_error,"bad lon: %f\n",lon); return 20; } fprintf (fp,"%9.4f",lon); /* Char 55: fixed epicentre flag.*/ if (!(epifix == ' ' || epifix == 'f')){ sprintf (isf_bulletin_error,"bad epifix: %c\n",epifix); return 20; } fprintf (fp,"%c",epifix); /* Char 56 should be a space but then can't have 5 digit smaj. */ /* Chars 56-60: optional semi-major axis. Char 61: space. */ /* printf gives at least 1 decimal place but 0 if number > 999. */ if (is_null(smaj)){ fprintf (fp," "); } else{ if ( smaj < 0 || smaj > 99999 ){ sprintf (isf_bulletin_error,"bad smaj: %f\n",smaj); return 20; } print_float(fp,smaj,5,1); fprintf(fp," "); } /* Chars 62-66: optional semi-minor axis. Char 67: space. */ /* printf gives at least 1 decimal place but 0 if number > 999. */ if (is_null(smin)){ fprintf (fp," "); } else{ if ( smin < 0 || smin > 99999 ){ sprintf (isf_bulletin_error,"bad smin: %f\n",smin); return 20; } print_float(fp,smin,5,1); fprintf(fp," "); } /* Chars 68-70: optional strike. Char 71: space. */ /* Strike can be -1, when it's a flag to signify that smaj,smin */ /* are really slat,slon. */ if (is_null(strike)){ fprintf (fp," "); } else{ if ( strike < -1 || strike > 360 ){ sprintf (isf_bulletin_error,"bad strike: %d\n",strike); return 20; } fprintf (fp,"%3d ",strike); } /* Chars 72-76: optional depth. */ if (is_null(depth)){ fprintf (fp," "); } else{ if ( depth < 0 || depth > 999 ){ sprintf (isf_bulletin_error,"bad depth: %f\n",depth); return 20; } fprintf (fp,"%5.1f",depth); } /* Char 77: fixed depth flag. Char 78: space.*/ if (depfix != ' ' && depfix != 'f' && depfix != 'd'){ sprintf (isf_bulletin_error,"bad depfix: %c\n",depfix); return 20; } fprintf (fp,"%c ",depfix); /* Chars 79-82: optional depth error. Char 83: space. */ /* printf gives 1 decimal place or 0 if number > 99 */ if (is_null(sdepth)){ fprintf (fp," "); } else{ if ( sdepth < 0 || sdepth > 9999 ){ sprintf (isf_bulletin_error,"bad sdepth: %f\n",sdepth); return 20; } print_float(fp,sdepth,4,1); fprintf(fp," "); } /* Chars 84-87: optional ndef. Char 88: space. */ if (is_null(ndef)){ fprintf (fp," "); } else{ if ( ndef < 0 || ndef > 9999 ){ sprintf (isf_bulletin_error,"bad ndef: %d\n",ndef); return 20; } fprintf (fp,"%4d ",ndef); } /* Chars 89-92: optional nsta. Char 93: space. */ if (is_null(nsta)){ fprintf (fp," "); } else{ if ( nsta < 0 || nsta > 9999 ){ sprintf (isf_bulletin_error,"bad nsta: %d\n",nsta); return 20; } fprintf (fp,"%4d ",nsta); } /* Chars 94-96: optional gap. Char 97: space. */ if (is_null(gap)){ fprintf (fp," "); } else{ if ( gap < 0 || gap > 360 ){ sprintf (isf_bulletin_error,"bad gap: %d\n",gap); return 20; } fprintf (fp,"%3d ",gap); } /* Chars 98-103: optional minimum distance. Char 104: space. */ /* printf gives at least 2 decimal places but less if number > 999. */ if (is_null(mindist)){ fprintf (fp," "); } else{ if ( mindist < 0 || mindist > 999999 ){ sprintf (isf_bulletin_error,"bad mindist: %f\n",mindist); return 20; } print_float(fp,mindist,6,2); fprintf(fp," "); } /* Chars 105-110: optional maximum distance. Char 111: space. */ /* printf gives at least 2 decimal places but less if number > 999. */ if (is_null(maxdist)){ fprintf (fp," "); } else{ if ( maxdist < 0 || maxdist > 999999 ){ sprintf (isf_bulletin_error,"bad maxdist: %f\n",maxdist); return 20; } print_float(fp,maxdist,6,2); fprintf(fp," "); } /* Char 112: analysis type. Char 113 space. */ if (antype != ' ' && antype != 'a' && antype != 'm' && antype != 'g'){ sprintf (isf_bulletin_error,"bad antype: %c\n",antype); return 20; } fprintf (fp,"%c ",antype); /* Char 114: location method. Char 115 space. */ if (loctype != ' ' && loctype != 'i' && loctype != 'p' && \ loctype != 'g' && loctype != 'o'){ sprintf (isf_bulletin_error,"bad loctype: %c\n",loctype); return 20; } fprintf (fp,"%c ",loctype); /* Chars 116-117: event type. Char 118 space. */ if (etype[0] == '\0' ){ fprintf (fp,"%*s ",ISF_ETYPE_LEN," "); } else{ if (strlen(etype) > ISF_ETYPE_LEN ){ sprintf (isf_bulletin_error,"etype wrong length: %s\n",etype); return 20; } fprintf (fp,"%*s ",ISF_ETYPE_LEN,etype); } /* Chars 119-127: author. Char 128: space. */ if (author[0] == '\0' ){ sprintf (isf_bulletin_error,"missing author\n"); return 20; } if (strlen(author) > ISF_AUTHOR_LEN ){ sprintf (isf_bulletin_error,"author too long: %s\n",author); return 20; } if (check_whole(author)){ sprintf (isf_bulletin_error,"bad author: %s\n",author); return 20; } fprintf (fp,"%-*s ",ISF_AUTHOR_LEN,author); /* Chars 129-136: origid. */ if (origid[0] == '\0' ){ sprintf (isf_bulletin_error,"missing origid\n"); return 20; } if (strlen(origid) > ISF_ORIGID_LEN ){ sprintf (isf_bulletin_error,"origid too long: %s\n",origid); return 1; } if (check_whole(origid)){ sprintf (isf_bulletin_error,"bad origid: %s\n",origid); return 20; } fprintf (fp,"%-*s\n",ISF_ORIGID_LEN,origid); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes the comment that can follow an origin line to mark it is as prime. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_origin_prime(FILE *fp) { char line_type[] = "origin_com"; fprintf (fp,"%s\n"," (#PRIME)"); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes the comment that can follow an origin line to mark it is a centroid. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_origin_centroid(FILE *fp) { char line_type[] = "origin_com"; fprintf (fp,"%s\n"," (#CENTROID)"); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes an origin parameter formatted comment. Writes any number of parameter=value pairs, starting new line if necessary. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_origin_param(FILE *fp, char **param, char **value, char **error, int numparam) { char line_type[] = "origin_com"; int i,len,space_left; fprintf (fp," (#PARAM"); space_left = ISF_COMM_LEN; for (i=0;i ISF_COMM_LEN){ sprintf (isf_bulletin_error,"%s=%s too long",param[i],value[i]); return 20; } if (space_left < len){ fprintf (fp,")\n (#PARAM"); space_left = ISF_COMM_LEN; } fprintf (fp," %s=%s",param[i],value[i]); if (error[i][0] != '\0'){ fprintf (fp,"+%s",error[i]); } space_left -= len; } fprintf (fp,")\n"); if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes both moment tensor header lines. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_momten_head(FILE *fp){ char line_type[] = "momten_head"; char head1[] = " (#MOMTENS sc M0 fCLVD MRR MTT MPP MRT MTP MPR NST1 NST2 Author )"; char head2[] = " (# eM0 eCLVD eRR eTT ePP eRT eTP ePR NCO1 NCO2 Duration )"; fprintf(fp,"%s\n",head1); fprintf(fp,"%s\n",head2); if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes both moment tensor data lines. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_momten(FILE *fp, int scale_factor, float scalar_moment, float fclvd, float mrr, float mtt, float mpp, float mrt, float mtp, float mpr, int nsta1, int nsta2, char *author, float scalar_moment_unc, float fclvd_unc, float mrr_unc, float mtt_unc, float mpp_unc, float mrt_unc, float mtp_unc, float mpr_unc, int ncomp1, int ncomp2, float duration ) { char line_type[] = "momten"; /* Line 1 */ /* Chars 1-11: the string ' (# ' */ fprintf (fp," (# "); /* Chars 12,13: scale factor. Char 14: space. */ if (is_null(scale_factor)){ sprintf (isf_bulletin_error,"missing scale_factor\n"); return 20; } if ( scale_factor < 0 || scale_factor > 99 ){ sprintf (isf_bulletin_error,"bad scale_factor: %d\n",scale_factor); return 20; } fprintf (fp,"%2d ",scale_factor); /* Chars 15-19: scalar seismic moment. Char 20: space. */ if (is_null(scalar_moment)){ sprintf (isf_bulletin_error,"missing scalar_moment\n"); return 20; } if (scalar_moment < 0 || scalar_moment > 9.999){ sprintf (isf_bulletin_error,"bad scalar_moment: %f\n",scalar_moment); return 20; } fprintf (fp,"%5.3f ",scalar_moment); /* Chars 21-25: fCLVD. Char 26: space. */ if (is_null(fclvd)){ fprintf (fp," "); } else{ if ( fclvd < 0 || fclvd > 9.999 ){ sprintf (isf_bulletin_error,"bad fclvd: %f\n",fclvd); return 20; } fprintf (fp,"%5.3f ",fclvd); } /* Chars 27-32: radial-radial element. Char 33: space. */ if (is_null(mrr)){ fprintf (fp," "); } else{ if ( mrr < -9.999 || mrr > 9.999 ){ sprintf (isf_bulletin_error,"bad mrr: %f\n",mrr); return 20; } fprintf (fp,"%6.3f ",mrr); } /* Chars 34-39: theta-theta element. Char 40: space. */ if (is_null(mtt)){ fprintf (fp," "); } else{ if ( mtt < -9.999 || mtt > 9.999 ){ sprintf (isf_bulletin_error,"bad mtt: %f\n",mtt); return 20; } fprintf (fp,"%6.3f ",mtt); } /* Chars 41-46: phi-phi element. Char 47: space. */ if (is_null(mpp)){ fprintf (fp," "); } else{ if ( mpp < -9.999 || mpp > 9.999 ){ sprintf (isf_bulletin_error,"bad mpp: %f\n",mpp); return 20; } fprintf (fp,"%6.3f ",mpp); } /* Chars 48-53: radial-theta element. Char 54: space. */ if (is_null(mrt)){ fprintf (fp," "); } else{ if ( mrt < -9.999 || mrt > 9.999 ){ sprintf (isf_bulletin_error,"bad mrt: %f\n",mrt); return 20; } fprintf (fp,"%6.3f ",mrt); } /* Chars 55-60: theta-phi element. Char 61: space. */ if (is_null(mtp)){ fprintf (fp," "); } else{ if ( mtp < -9.999 || mtp > 9.999 ){ sprintf (isf_bulletin_error,"bad mtp: %f\n",mtp); return 20; } fprintf (fp,"%6.3f ",mtp); } /* Chars 62-67: phi-radial element. Char 68: space. */ if (is_null(mpr)){ fprintf (fp," "); } else{ if ( mpr < -9.999 || mpr > 9.999 ){ sprintf (isf_bulletin_error,"bad mpr: %f\n",mpr); return 20; } fprintf (fp,"%6.3f ",mpr); } /* Chars 69-72: nsta1. Char 73: space. */ if (is_null(nsta1)){ fprintf (fp," "); } else{ if ( nsta1 < 0 || nsta1 > 999 ){ sprintf (isf_bulletin_error,"bad nsta1: %d\n",nsta1); return 20; } fprintf (fp,"%4d ",nsta1); } /* Chars 74-77: nsta2. Char 78: space. */ if (is_null(nsta2)){ fprintf (fp," "); } else{ if ( nsta2 < 0 || nsta2 > 999 ){ sprintf (isf_bulletin_error,"bad nsta2: %d\n",nsta2); return 20; } fprintf (fp,"%4d ",nsta2); } /* Chars 79-87 author. Char 87 ')'. */ if (author[0] == '\0' ){ sprintf (isf_bulletin_error,"missing author\n"); return 20; } if (strlen(author) > ISF_AUTHOR_LEN ){ sprintf (isf_bulletin_error,"author too long: %s\n",author); return 20; } if (check_whole(author)){ sprintf (isf_bulletin_error,"bad author: %s\n",author); return 20; } fprintf (fp,"%-*s)\n",ISF_AUTHOR_LEN,author); /* Line 2 */ /* Chars 1-14: the string ' (# ' */ fprintf (fp," (# "); /* Chars 15-19: uncertainty in scalar seismic moment. Char 20: space. */ if (is_null(scalar_moment_unc)){ fprintf (fp," "); } else{ if (scalar_moment_unc < 0 || scalar_moment_unc > 9.999){ sprintf (isf_bulletin_error,"bad scalar_moment_unc: %f\n" \ ,scalar_moment_unc); return 20; } fprintf (fp,"%5.3f ",scalar_moment_unc); } /* Chars 21-25: uncertainty in fCLVD. Char 26: space. */ if (is_null(fclvd_unc)){ fprintf (fp," "); } else{ if ( fclvd_unc < 0 || fclvd_unc > 9.999 ){ sprintf (isf_bulletin_error,"bad fclvd_unc: %f\n",fclvd_unc); return 20; } fprintf (fp,"%5.3f ",fclvd_unc); } /* Chars 27-32: uncertainty in radial-radial element. Char 33: space. */ if (is_null(mrr_unc)){ fprintf (fp," "); } else{ if ( mrr_unc < 0 || mrr_unc > 9.999 ){ sprintf (isf_bulletin_error,"bad mrr_unc: %f\n",mrr_unc); return 20; } fprintf (fp,"%6.3f ",mrr_unc); } /* Chars 34-39: uncertainty in theta-theta element. Char 40: space. */ if (is_null(mtt_unc)){ fprintf (fp," "); } else{ if ( mtt_unc < 0 || mtt_unc > 9.999 ){ sprintf (isf_bulletin_error,"bad mtt_unc: %f\n",mtt_unc); return 20; } fprintf (fp,"%6.3f ",mtt_unc); } /* Chars 41-46: uncertainty in phi-phi element. Char 47: space. */ if (is_null(mpp_unc)){ fprintf (fp," "); } else{ if ( mpp_unc < 0 || mpp_unc > 9.999 ){ sprintf (isf_bulletin_error,"bad mpp_unc: %f\n",mpp_unc); return 20; } fprintf (fp,"%6.3f ",mpp_unc); } /* Chars 48-53: uncertainty in radial-theta element. Char 54: space. */ if (is_null(mrt_unc)){ fprintf (fp," "); } else{ if ( mrt_unc < 0 || mrt_unc > 9.999 ){ sprintf (isf_bulletin_error,"bad mrt_unc: %f\n",mrt_unc); return 20; } fprintf (fp,"%6.3f ",mrt_unc); } /* Chars 55-60: uncertainty in theta-phi element. Char 61: space. */ if (is_null(mtp_unc)){ fprintf (fp," "); } else{ if ( mtp_unc < 0 || mtp_unc > 9.999 ){ sprintf (isf_bulletin_error,"bad mtp_unc: %f\n",mtp_unc); return 20; } fprintf (fp,"%6.3f ",mtp_unc); } /* Chars 62-67: uncertainty in phi-radial element. Char 68: space. */ if (is_null(mpr_unc)){ fprintf (fp," "); } else{ if ( mpr_unc < 0 || mpr_unc > 9.999 ){ sprintf (isf_bulletin_error,"bad mpr_unc: %f\n",mpr_unc); return 20; } fprintf (fp,"%6.3f ",mpr_unc); } /* Chars 69-72: ncomp1. Char 73: space. */ if (is_null(ncomp1)){ fprintf (fp," "); } else{ if ( ncomp1 < 0 || ncomp1 > 999 ){ sprintf (isf_bulletin_error,"bad ncomp1: %d\n",ncomp1); return 20; } fprintf (fp,"%4d ",ncomp1); } /* Chars 74-77: ncomp2. Char 78: space. */ if (is_null(ncomp2)){ fprintf (fp," "); } else{ if ( ncomp2 < 0 || ncomp2 > 999 ){ sprintf (isf_bulletin_error,"bad ncomp2: %d\n",ncomp2); return 20; } fprintf (fp,"%4d ",ncomp2); } /* Chars 79-86: duration. Char 77: space. Char 88 ')'. */ if (is_null(duration)){ fprintf (fp," )\n"); } else{ if ( duration < 0 || duration > 99999 ){ sprintf (isf_bulletin_error,"bad duration: %f\n",duration); return 20; } fprintf (fp,"%8.2f )\n",duration); } /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a fault plane header line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_fault_plane_head (FILE *fp){ char line_type[] = "fault_plane_head"; char head[] = " (#FAULT_PLANE Typ Strike Dip Rake NP NS Plane Author )"; fprintf(fp,"%s\n",head); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a fault plane data line. Either first or second plane - only the comment marker at the start changes. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_fault_plane (FILE *fp, char *f_type, float strike, float dip, float rake, int np, int ns, char *f_plane, char *author) { char line_type[] = "fault_plane"; int line_num; /* Check if this is the second fault plane to be writen */ /* Chars 1-15 are the respective comment start strings. */ if (strcmp(isf_prev_line_type,"fault_plane") == 0){ line_num = 2; fprintf(fp," (+ "); } else { line_num = 1; fprintf(fp," (# "); } /* Chars 16-18: Fault plane type. Char 19: space */ if ( f_type[0] != '\0' ){ if ( strlen(f_type) > ISF_F_TYPE_LEN ){ sprintf (isf_bulletin_error,"f_type too long: %s\n",f_type); return 20; } if (check_whole(f_type)){ sprintf (isf_bulletin_error,"bad f_type: %s\n",f_type); return 20; } fprintf (fp,"%-*s ",ISF_F_TYPE_LEN,f_type); } else { fprintf (fp,"%*s ",ISF_F_TYPE_LEN,""); } /* Chars 20-25: strike. Char 26 space. */ if (is_null(strike)){ sprintf (isf_bulletin_error,"missing strike\n"); return 20; } if (strike < 0 || strike > 360){ sprintf (isf_bulletin_error,"bad strike: %f\n",strike); return 20; } fprintf (fp,"%6.2f ",strike); /* Chars 27-31: dip. Char 32 space. */ if (is_null(dip)){ sprintf (isf_bulletin_error,"missing dip\n"); return 20; } if (dip < 0 || dip > 90){ sprintf (isf_bulletin_error,"bad dip: %f\n",dip); return 20; } fprintf (fp,"%5.2f ",dip); /* Chars 33-39: optional rake. Char 40 space. */ if (is_null(rake)){ fprintf (fp," "); } else { if (rake < -180 || rake > 180){ sprintf (isf_bulletin_error,"bad rake: %f\n",rake); return 20; } fprintf (fp,"%7.2f ",rake); } /* Chars 41-43: optional np. Char 44 space. */ if (is_null(np)){ fprintf (fp," "); } else { if (np < 0 || np > 999){ sprintf (isf_bulletin_error,"bad np: %f\n",np); return 20; } fprintf (fp,"%3d ",np); } /* Chars 45-47: optional ns. Char 48 space. */ if (is_null(ns)){ fprintf (fp," "); } else { if (ns < 0 || ns > 999){ sprintf (isf_bulletin_error,"bad ns: %f\n",ns); return 20; } fprintf (fp,"%3d ",ns); } /* Chars 49-53: Plane identification. Char 54: space. */ if ( f_plane[0] != '\0' ){ if ( strlen(f_plane) > ISF_F_PLANE_LEN ){ sprintf (isf_bulletin_error,"f_plane too long: %s\n",f_plane); return 20; } if (check_whole(f_plane)){ sprintf (isf_bulletin_error,"bad f_plane: %s\n",f_plane); return 20; } fprintf (fp,"%-*s ",ISF_F_PLANE_LEN,f_plane); } else { fprintf (fp,"%*s ",ISF_F_PLANE_LEN,""); } /* Chars 55-63: author if this is 1st fault plane. Char 64: ')'. */ if (line_num == 1){ if (author[0] == '\0' ){ sprintf (isf_bulletin_error,"missing author\n"); return 20; } if ( strlen(author) > ISF_AUTHOR_LEN ){ sprintf (isf_bulletin_error,"author too long: %s\n",author); return 20; } if (check_whole(author)){ sprintf (isf_bulletin_error,"bad author: %s\n",author); return 20; } fprintf (fp,"%-*s)\n",ISF_AUTHOR_LEN,author); } else { fprintf (fp," )\n"); } /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a principal axes header line. Returns 0 on a successful write. Returns 10 if these lines should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_axes_head(FILE *fp) { char line_type[] = "axes_head"; char head[] = " (#PRINAX sc T_val T_azim T_pl B_val B_azim B_pl P_val P_azim P_pl Author )"; fprintf(fp,"%s\n",head); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a principal axes error header line. Returns 0 on a successful write. Returns 10 if these lines should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_axes_err_head(FILE *fp) { char line_type[] = "axes_err_head"; char head[] = " (+ eTv eTa eTp eBv eBa eBp ePv ePa ePp fCLVD )"; fprintf(fp,"%s\n",head); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a principal axes data line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_axes( FILE *fp, int scale_factor, float t_val, float t_azim, float t_pl, float b_val, float b_azim, float b_pl, float p_val, float p_azim, float p_pl, char *author) { char line_type[] = "axes"; /* Chars 1-10: Comment start string. */ fprintf(fp," (# "); /* Chars 11,12: scale factor. Char 13: space. */ if (is_null(scale_factor)){ fprintf(fp," "); } else { if (scale_factor < 0 || scale_factor > 99){ sprintf (isf_bulletin_error,"bad scale_factor: %d\n",scale_factor); return 20; } fprintf (fp,"%2d ",scale_factor); } /* Chars 14-19: t_val. Char 20: space */ if (is_null(t_val)){ fprintf(fp," "); } else { if (t_val < -9.999 || t_val > 9.999){ sprintf (isf_bulletin_error,"bad t_val: %f\n",t_val); return 20; } fprintf (fp,"%6.3f ",t_val); } /* Chars 21-26: t_azim. Char 27 space. */ if (is_null(t_azim)){ sprintf (isf_bulletin_error,"missing t_azim\n"); return 20; } if (t_azim < 0 || t_azim > 360){ sprintf (isf_bulletin_error,"bad t_azim: %f\n",t_azim); return 20; } fprintf (fp,"%6.2f ",t_azim); /* Chars 28-32: t_pl. Char 33 space. */ if (is_null(t_pl)){ sprintf (isf_bulletin_error,"missing t_pl\n"); return 20; } if (t_pl < 0 || t_pl > 90){ sprintf (isf_bulletin_error,"bad t_pl: %f\n",t_pl); return 20; } fprintf (fp,"%5.2f ",t_pl); /* Chars 34-39: b_val. Char 40: space */ if (is_null(b_val)){ fprintf(fp," "); } else { if (b_val < -9.999 || b_val > 9.999){ sprintf (isf_bulletin_error,"bad b_val: %f\n",b_val); return 20; } fprintf (fp,"%6.3f ",b_val); } /* Chars 41-46: b_azim. Char 47 space. */ if (is_null(b_azim)){ sprintf (isf_bulletin_error,"missing b_azim\n"); return 20; } if (b_azim < 0 || b_azim > 360){ sprintf (isf_bulletin_error,"bad b_azim: %f\n",b_azim); return 20; } fprintf (fp,"%6.2f ",b_azim); /* Chars 48-52: b_pl. Char 53 space. */ if (is_null(b_pl)){ sprintf (isf_bulletin_error,"missing b_pl\n"); return 20; } if (b_pl < 0 || b_pl > 90){ sprintf (isf_bulletin_error,"bad b_pl: %f\n",b_pl); return 20; } fprintf (fp,"%5.2f ",b_pl); /* Chars 54-59: p_val. Char 60: space */ if (is_null(p_val)){ fprintf(fp," "); } else { if (p_val <= -10 || p_val >= 10){ sprintf (isf_bulletin_error,"bad p_val: %f\n",p_val); return 20; } fprintf (fp,"%6.3f ",p_val); } /* Chars 61-66: p_azim. Char 67 space. */ if (is_null(p_azim)){ sprintf (isf_bulletin_error,"missing p_azim\n"); return 20; } if (p_azim < 0 || p_azim > 360){ sprintf (isf_bulletin_error,"bad b_azim: %f\n",p_azim); return 20; } fprintf (fp,"%6.2f ",p_azim); /* Chars 68-72: p_pl. Char 73 space. */ if (is_null(p_pl)){ sprintf (isf_bulletin_error,"missing p_pl\n"); return 20; } if (p_pl < 0 || p_pl > 90){ sprintf (isf_bulletin_error,"bad p_pl: %f\n",p_pl); return 20; } fprintf (fp,"%5.2f ",p_pl); /* Chars 74-82: author. Char 83: close bracket. */ if (author[0] == '\0' ){ sprintf (isf_bulletin_error,"missing author\n"); return 20; } if (strlen(author) > ISF_AUTHOR_LEN){ sprintf (isf_bulletin_error,"author too long: %s\n",author); return 20; } if (check_whole(author)){ sprintf (isf_bulletin_error,"bad author: %s\n",author); return 20; } fprintf (fp,"%-*s)\n",ISF_AUTHOR_LEN,author); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Write principal axes error line - allows anything and everthing to be null. Would be possible to want to write only fCVLD or only errors. Trust user not to send for it if have nothing at all to write. Returns 0 on a successful write. Returns 10 if these lines should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_axes_err(FILE *fp, float t_val_unc, float t_azim_unc, float t_pl_unc, float b_val_unc, float b_azim_unc, float b_pl_unc, float p_val_unc, float p_azim_unc, float p_pl_unc, float fclvd) { char line_type[] = "axes_err"; /* Chars 1-14: Comment start string. */ fprintf(fp," (+ "); /* Chars 15-19: t_val_unc. Char 20: space */ if (is_null(t_val_unc)){ fprintf(fp," "); } else { if (t_val_unc < 0 || t_val_unc > 9.999){ sprintf (isf_bulletin_error,"bad t_val_unc: %f\n",t_val_unc); return 20; } fprintf (fp,"%5.3f ",t_val_unc); } /* Chars 21-26: t_azim_unc. Char 27: space */ if (is_null(t_azim_unc)){ fprintf(fp," "); } else { if (t_azim_unc < 0 || t_azim_unc > 360){ sprintf (isf_bulletin_error,"bad t_azim_unc: %f\n",t_azim_unc); return 20; } fprintf (fp,"%6.2f ",t_azim_unc); } /* Chars 28-32: t_pl_unc. Char 33,34: spaces */ if (is_null(t_pl_unc)){ fprintf(fp," "); } else { if (t_pl_unc < 0 || t_pl_unc > 90){ sprintf (isf_bulletin_error,"bad t_pl_unc: %f\n",t_pl_unc); return 20; } fprintf (fp,"%5.2f ",t_pl_unc); } /* Chars 35-39: b_val_unc. Char 40: space */ if (is_null(b_val_unc)){ fprintf(fp," "); } else { if (b_val_unc < 0 || b_val_unc >= 10){ sprintf (isf_bulletin_error,"bad b_val_unc: %f\n",b_val_unc); return 20; } fprintf (fp,"%5.3f ",b_val_unc); } /* Chars 41-46: b_azim_unc. Char 47: space */ if (is_null(b_azim_unc)){ fprintf(fp," "); } else { if (b_azim_unc < 0 || b_azim_unc > 360){ sprintf (isf_bulletin_error,"bad b_azim_unc: %f\n",b_azim_unc); return 20; } fprintf (fp,"%6.2f ",b_azim_unc); } /* Chars 48-52: b_pl_unc. Char 53,54: spaces */ if (is_null(b_pl_unc)){ fprintf(fp," "); } else { if (b_pl_unc < 0 || b_pl_unc > 90){ sprintf (isf_bulletin_error,"bad b_pl_unc: %f\n",b_pl_unc); return 20; } fprintf (fp,"%5.2f ",b_pl_unc); } /* Chars 55-59: p_val_unc. Char 60: space */ if (is_null(p_val_unc)){ fprintf(fp," "); } else { if (p_val_unc < 0 || p_val_unc >= 10){ sprintf (isf_bulletin_error,"bad p_val_unc: %f\n",p_val_unc); return 20; } fprintf (fp,"%5.3f ",p_val_unc); } /* Chars 61-66: p_azim_unc. Char 67: space */ if (is_null(p_azim_unc)){ fprintf(fp," "); } else { if (p_azim_unc < 0 || p_azim_unc > 360){ sprintf (isf_bulletin_error,"bad p_azim_unc: %f\n",p_azim_unc); return 20; } fprintf (fp,"%6.2f ",p_azim_unc); } /* Chars 68-72: p_pl_unc. Char 73: space */ if (is_null(p_pl_unc)){ fprintf(fp," "); } else { if (p_pl_unc < 0 || p_pl_unc > 90){ sprintf (isf_bulletin_error,"bad p_pl_unc: %f\n",p_pl_unc); return 20; } fprintf (fp,"%5.2f ",p_pl_unc); } /* Chars 74-78: fclvd. Chars 79-82: spaces to line up close brackets */ if (is_null(fclvd)){ fprintf(fp," )\n"); } else { if (fclvd < 0 || fclvd > 1){ sprintf (isf_bulletin_error,"bad fclvd: %f\n",fclvd); return 20; } fprintf (fp,"%5.3f )\n",fclvd); } if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes magnitude header complete with preceding blank line. Returns 0 on a successful write. Returns 10 if these lines should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_netmag_head(FILE *fp){ char line_type[] = "netmag_head"; char head[] = "Magnitude Err Nsta Author OrigID"; fprintf(fp,"\n%s\n",head); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a magnitude data line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_netmag( FILE *fp, char* magtype, char magind, float mag, float magerr, int nsta, char* author, char *origid){ char line_type[] = "netmag"; /* Chars 1-5: magtype. */ if ( magtype[0] == '\0' ){ sprintf (isf_bulletin_error,"missing magtype\n"); return 20; } if ( strlen(magtype) > ISF_MAGTYPE_LEN ){ sprintf (isf_bulletin_error,"magtype too long: %s\n",magtype); return 20; } if (check_whole(magtype)){ sprintf (isf_bulletin_error,"bad magtype: %s\n",magtype); return 20; } fprintf (fp,"%-*s",ISF_MAGTYPE_LEN,magtype); /* Char 6: less than or greater than indicator */ if (magind != ' ' && magind != '<' && magind != '>'){ sprintf (isf_bulletin_error,"bad magind: %c\n",magind); return 20; } fprintf (fp,"%c",magind); /* Chars 7-10: magnitude value. Char 11 space. */ if (is_null(mag)){ sprintf (isf_bulletin_error,"missing mag\n"); return 20; } if (mag < -1 || mag > 12){ sprintf (isf_bulletin_error,"bad magnitude: %f\n",mag); return 20; } fprintf (fp,"%4.1f ",mag); /* Chars 12-14: optional magnitude error. Char 15: space. */ if (is_null(magerr)){ fprintf (fp," "); } else{ if (magerr < 0 || magerr > 9.9){ sprintf (isf_bulletin_error,"bad magerr: %f\n",magerr); return 20; } fprintf (fp,"%3.1f ",magerr); } /* Chars 16-19 optional number of stations. Char 20: space. */ if (is_null(nsta)){ fprintf (fp," "); } else { if (nsta < 0 || nsta > 9999){ sprintf (isf_bulletin_error,"bad nsta: %f\n",nsta); return 20; } fprintf (fp,"%4d ",nsta); } /* Chars 21-29 author. Char 30 space. */ if (author[0] == '\0' ){ sprintf (isf_bulletin_error,"missing author\n"); return 20; } if (strlen(author) > ISF_AUTHOR_LEN ){ sprintf (isf_bulletin_error,"author too long: %s\n",author); return 20; } if (check_whole(author)){ sprintf (isf_bulletin_error,"bad author: %s\n",author); return 20; } fprintf (fp,"%-*s ",ISF_AUTHOR_LEN,author); /* Chars 31-38 origid. */ if (origid[0] == '\0' ){ sprintf (isf_bulletin_error,"missing origid\n"); return 20; } if (strlen(origid) > ISF_ORIGID_LEN ){ sprintf (isf_bulletin_error,"origid too long: %s\n",origid); return 1; } if (check_whole(origid)){ sprintf (isf_bulletin_error,"bad origid: %s\n",origid); return 20; } fprintf (fp,"%-*s\n",ISF_ORIGID_LEN,origid); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a list of the stations that were used to calculate a magnitude. Will write any number, starting new lines as necessary. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_netmag_sta( FILE *fp, char **sta, int n) { int i; int sta_len,data_len; char line_type[] = "netmag_com"; fprintf(fp," (#STATIONS"); data_len = -1; /* Don't include the space after #STATIONS */ for (i=0; i ISF_NET_LEN+ISF_STA_LEN){ sprintf (isf_bulletin_error,"net/sta code too long: %s\n",sta[i]); return 20; } data_len += sta_len+1; if (data_len > ISF_COMM_LEN){ fprintf(fp,")\n (+ "); data_len=sta_len+1; } fprintf(fp," %s",sta[i]); } fprintf(fp,")\n"); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a netmag basis data line. Only expects one parameter=value pair. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_netmag_basis(FILE *fp, char *param, char *value) { char line_type[] = "netmag_com"; if ((strlen(param) + strlen(value) + 1) > ISF_COMM_LEN){ sprintf (isf_bulletin_error,"too long: %s=%s\n",param,value); return 20; } fprintf(fp," (#BASIS %s=%s)\n",param,value); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes effects header complete with preceding blank line. Returns 0 on a successful write. Returns 10 if these lines should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_effects_head(FILE *fp){ char line_type[] = "effects_head"; char head[] = "Effects Loctyp Location Intensity Scale Author"; fprintf(fp,"\n%s\n",head); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes an effects block data line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_effects(FILE *fp, char heard, char felt, char damage, char casualties, char uplift, char subsidence, char fault, char tsunami, char seiche, char volcano, char acoustic, char gravity, char t_wave, char liquification, char geyser, char landslide, char sandblow, char cracks, char lights, char odours, char *loctype, float lat, float lon, float dist, float azim, char *country, char *postcode, char *net, char *sta, float intensity1, char modifier, float intensity2, char *scale, char* author) { char line_type[] = "effects"; /* Char 1: heard flag */ if (heard != 'H' && heard != '_'){ sprintf (isf_bulletin_error,"bad heard flag: %c",heard); return 20; } fprintf (fp,"%c",heard); /* Char 2: felt flag */ if (felt != 'F' && felt != '_'){ sprintf (isf_bulletin_error,"bad felt flag: %c",felt); return 20; } fprintf (fp,"%c",felt); /* Char 3: damage flag */ if (damage != 'D' && damage != '_'){ sprintf (isf_bulletin_error,"bad damage flag: %c",damage); return 20; } fprintf (fp,"%c",damage); /* Char 4: casualties flag */ if (casualties != 'C' && casualties != '_'){ sprintf (isf_bulletin_error,"bad casualties flag: %c",casualties); return 20; } fprintf (fp,"%c",casualties); /* Char 5: uplift flag */ if (uplift != 'U' && uplift != '_'){ sprintf (isf_bulletin_error,"bad uplift flag: %c",uplift); return 20; } fprintf (fp,"%c",uplift); /* Char 6: subsidence flag */ if (subsidence != 'S' && subsidence != '_'){ sprintf (isf_bulletin_error,"bad subsidence flag: %c",subsidence); return 20; } fprintf (fp,"%c",subsidence); /* Char 7 surface faulting flag */ if (fault != 'F' && fault != '_'){ sprintf (isf_bulletin_error,"bad fault flag: %c",fault); return 20; } fprintf (fp,"%c",fault); /* Char 8 tsunami flag */ if (tsunami != 'T' && tsunami != 'Q' && tsunami != '_'){ sprintf (isf_bulletin_error,"bad tsunami flag: %c",tsunami); return 20; } fprintf (fp,"%c",tsunami); /* Char 9 seiche flag */ if (seiche != 'S' && seiche != 'Q' && seiche != '_'){ sprintf (isf_bulletin_error,"bad seiche flag: %c",seiche); return 20; } fprintf (fp,"%c",seiche); /* Char 10 volcano flag */ if (volcano != 'V' && volcano != '_'){ sprintf (isf_bulletin_error,"bad volcano flag: %c",volcano); return 20; } fprintf (fp,"%c",volcano); /* Char 11 acoustic flag */ if (acoustic != 'A' && acoustic != '_'){ sprintf (isf_bulletin_error,"bad acoustic flag: %c",acoustic); return 20; } fprintf (fp,"%c",acoustic); /* Char 12 gravity flag */ if (gravity != 'G' && gravity != '_'){ sprintf (isf_bulletin_error,"bad gravity flag: %c",gravity); return 20; } fprintf (fp,"%c",gravity); /* Char 13 t_wave flag */ if (t_wave != 'T' && t_wave != '_'){ sprintf (isf_bulletin_error,"bad t_wave flag: %c",t_wave); return 20; } fprintf (fp,"%c",t_wave); /* Char 14 liquification flag */ if (liquification != 'L' && liquification != '_'){ sprintf(isf_bulletin_error,"bad liquification flag: %c",liquification); return 20; } fprintf (fp,"%c",liquification); /* Char 15 geyser flag */ if (geyser != 'G' && geyser != '_'){ sprintf (isf_bulletin_error,"bad geyser flag: %c",geyser); return 20; } fprintf (fp,"%c",geyser); /* Char 16 landslide flag */ if (landslide != 'S' && landslide != '_'){ sprintf (isf_bulletin_error,"bad landslide flag: %c",landslide); return 20; } fprintf (fp,"%c",landslide); /* Char 17 sandblow flag */ if (sandblow != 'B' && sandblow != '_'){ sprintf (isf_bulletin_error,"bad sandblow flag: %c",sandblow); return 20; } fprintf (fp,"%c",sandblow); /* Char 18 cracks flag */ if (cracks != 'C' && cracks != '_'){ sprintf (isf_bulletin_error,"bad cracks flag: %c",heard); return 20; } fprintf (fp,"%c",cracks); /* Char 19 lights flag */ if (lights != 'V' && lights != '_'){ sprintf (isf_bulletin_error,"bad lights flag: %c",lights); return 20; } fprintf (fp,"%c",lights); /* Char 20 odours flag. Char 21 space. */ if (odours != 'O' && odours != '_'){ sprintf (isf_bulletin_error,"bad odours flag: %c",odours); return 20; } fprintf (fp,"%c ",odours); /* Chars 22-27 loctype. Char 28 space. */ /* Chars 29-46 depend on loctype. Char 47: space. */ if (strcmp(loctype,"Summar")==0){ fprintf (fp,"%6s ",loctype); /* Chars 29-47 are blank */ fprintf (fp," "); } else if (strcmp(loctype,"LatLon")==0){ fprintf (fp,"%6s ",loctype); /* Chars 29-36: lattitude. Char 37: space. */ if (is_null(lat)){ sprintf (isf_bulletin_error,"missing lat\n"); return 20; } if (lat <= -90 || lat > 90){ sprintf (isf_bulletin_error,"bad lat: %f\n",lat); return 20; } fprintf (fp,"%8.4f ",lat); /* Chars 38-46: longitude. Char 47: space. */ if (is_null(lon)){ sprintf (isf_bulletin_error,"missing lon\n"); return 20; } if (lon < -180 || lon > 180){ sprintf (isf_bulletin_error,"bad lon: %f\n",lon); return 20; } fprintf (fp,"%9.4f ",lon); } else if (strcmp(loctype,"DistAz")==0){ fprintf (fp,"%6s ",loctype); /* Chars 29-36: distance. Char 37: space */ if (is_null(dist)){ sprintf (isf_bulletin_error,"missing dist\n"); return 20; } if (dist < 0 || dist > 99999){ sprintf (isf_bulletin_error,"bad dist: %f\n",dist); return 20; } fprintf (fp,"%8.2f ",dist); /* Chars 38-42: azimuth. Chars 43-47 space. */ if (is_null(azim)){ sprintf (isf_bulletin_error,"missing azim\n"); return 20; } if (azim < 0 || azim > 360){ sprintf (isf_bulletin_error,"bad azim: %f\n",azim); return 20; } fprintf (fp,"%5.1 ",azim); } else if (strcmp(loctype,"CoPost")==0){ fprintf (fp,"%6s ",loctype); /* Chars 29-31: country code. Chars 32 space. */ if (country[0] == '\0' ){ sprintf (isf_bulletin_error,"missing country\n"); return 20; } if (strlen(country) > ISF_COUNTRY_LEN ){ sprintf (isf_bulletin_error,"country too long: %s\n",country); return 1; } fprintf (fp,"%-*s ",ISF_COUNTRY_LEN,country); /* Chars 33-42: post code. Chars 43-47 space. */ if (postcode[0] == '\0' ){ sprintf (isf_bulletin_error,"missing postcode\n"); return 20; } if (strlen(postcode) > ISF_POSTCODE_LEN ){ sprintf (isf_bulletin_error,"postcode too long: %s\n",postcode); return 1; } fprintf (fp,"%-*s ",ISF_POSTCODE_LEN,postcode); } else if (strcmp(loctype,"StaNet")==0){ fprintf (fp,"%6s ",loctype); /* Chars 29-37: network code. Char 38: space. */ if (strlen(net) > ISF_NET_LEN ){ sprintf (isf_bulletin_error,"net too long: %s\n",net); return 1; } if (net[0] == '\0' ){ sprintf (isf_bulletin_error,"missing net\n"); return 20; } if (check_whole(net)){ sprintf (isf_bulletin_error,"bad net: %s\n",net); return 20; } fprintf (fp,"%-*s ",ISF_NET_LEN,net); /* Chars 39-43: station code. Chars 44-47: spaces. */ if (strlen(sta) > ISF_STA_LEN ){ sprintf (isf_bulletin_error,"sta too long: %s\n",sta); return 1; } if (sta[0] == '\0' ){ sprintf (isf_bulletin_error,"missing sta\n"); return 20; } if (check_whole(sta)){ sprintf (isf_bulletin_error,"bad sta: %s\n",sta); return 20; } fprintf (fp,"%-*s ",ISF_STA_LEN,sta); } else { sprintf (isf_bulletin_error,"unknown loctype: %s",loctype); return 20; } /* Chars 48-51: first intensity. */ /* If no first intensity then don't allow second one or scale. */ if (!is_null(intensity1)){ if (intensity1 < 0 || intensity1 > 12){ sprintf (isf_bulletin_error,"bad intensity1: %f\n",intensity1); return 20; } fprintf (fp,"%4.1f",intensity1); /* Char 52 intensity modifier */ if (modifier != ' ' && modifier != '-' && modifier != '+'){ sprintf (isf_bulletin_error,"bad intensity modifier: %c",modifier); return 20; } fprintf (fp,"%c",modifier); /* Chars 53-56: second intensity, only allowed if modifier is '-' */ /* Char 57: space */ if (modifier == '-'){ if (is_null(intensity2)){ sprintf (isf_bulletin_error,"missing intensity2\n"); return 20; } if (intensity2 < 0 || intensity2 > 12){ sprintf (isf_bulletin_error,"bad intensity2: %f\n",intensity2); return 20; } fprintf (fp,"%4.1f ",intensity2); } else { if (!is_null(intensity2)){ sprintf (isf_bulletin_error,"bad modifier if intensity2\n"); return 20; } fprintf (fp," "); } /* Chars 58-62: intensity scale. Char 63 space. */ if (scale[0] == '\0' ){ fprintf (fp,"%*s ",ISF_I_SCALE_LEN," "); } else { if (strlen(scale) > ISF_I_SCALE_LEN ){ sprintf (isf_bulletin_error,"scale too long: %s\n",scale); return 1; } if (check_whole(scale)){ sprintf (isf_bulletin_error,"bad scale: %s\n",scale); return 20; } fprintf (fp,"%-*s ",ISF_I_SCALE_LEN,scale); } } else { if (!is_null(intensity2)){ sprintf (isf_bulletin_error,"intensity2 without intensity1\n"); return 20; } if (modifier != ' ' ){ sprintf (isf_bulletin_error,"modifier without intensity1\n"); return 20; } if (scale[0] != '\0' ){ sprintf (isf_bulletin_error,"scale without intensity1\n"); return 20; } fprintf (fp," "); } /* Chars 64-72 author. */ if (author[0] == '\0' ){ sprintf (isf_bulletin_error,"missing author\n"); return 20; } if (strlen(author) > ISF_AUTHOR_LEN ){ sprintf (isf_bulletin_error,"author too long: %s\n",author); return 20; } if (check_whole(author)){ sprintf (isf_bulletin_error,"bad author: %s\n",author); return 20; } fprintf (fp,"%-*s\n",ISF_AUTHOR_LEN,author); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes phase header complete with preceding blank line. Returns 0 on a successful write. Returns 10 if these lines should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_phase_head(FILE *fp) { char line_type[] = "phase_head"; char head[] = "Sta Dist EvAz Phase Time TRes Azim AzRes Slow SRes Def SNR Amp Per Qual Magnitude ArrID"; fprintf(fp,"\n%s\n",head); if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a phase block data line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_phase(FILE *fp, char *sta, float dist, float esaz, char *phase, int hh, int mi, int ss, int msec, float timeres, float azim, float azimres, float slow, float slowres, char timedef, char azimdef, char slowdef, float snr, float amp, float per,char picktype, char sp_fm, char detchar, char *magtype, char magind, float mag, char *arrid) { char line_type[] = "phase"; /* Chars 1-5: station code. Char 6: space */ if (sta[0] == '\0' ){ sprintf (isf_bulletin_error,"missing sta\n"); return 20; } if (strlen(sta) > ISF_STA_LEN ){ sprintf (isf_bulletin_error,"sta too long: %s\n",sta); return 20; } if (check_whole(sta)){ sprintf (isf_bulletin_error,"bad sta: %s\n",sta); return 20; } fprintf (fp,"%-*s ",ISF_STA_LEN,sta); /* Chars 7-12: distance. Char 13: space */ if (is_null(dist)){ fprintf (fp," "); } else{ if (dist < 0 || dist > 999.99 ){ sprintf (isf_bulletin_error,"bad dist: %f\n",dist); return 20; } fprintf (fp,"%6.2f ",dist); } /* Chars 14-18: event to sta azimuth. Char 19: space */ if (is_null(esaz)){ fprintf (fp," "); } else{ if (esaz < 0 || esaz > 360 ){ sprintf (isf_bulletin_error,"bad esaz: %f\n",esaz); return 20; } fprintf (fp,"%5.1f ",esaz); } /* Chars 20-27: phase code - can be null. Char 28: space */ if (phase[0] == '\0' ){ fprintf (fp,"%*s ",ISF_PHASE_LEN,""); } else { if (strlen(phase) > ISF_PHASE_LEN ){ sprintf (isf_bulletin_error,"phase too long: %s\n",phase); return 20; } if (check_whole(phase)){ sprintf (isf_bulletin_error,"bad phase: %s\n",phase); return 20; } fprintf (fp,"%-*s ",ISF_PHASE_LEN,phase); } /* Chars 29-40: time. Char 41: space. */ /* Time can be completely null. */ if (is_null(hh) && is_null(mi) && is_null(ss)){ fprintf(fp," "); } else { if (is_null(hh)){ sprintf (isf_bulletin_error,"missing hour"); return 20; } if ( hh < 0 || hh > 23 ){ sprintf (isf_bulletin_error,"bad hour, %d",hh); return 20; } if (is_null(mi)){ sprintf (isf_bulletin_error,"missing minute"); return 20; } if ( mi < 0 || mi > 59 ){ sprintf (isf_bulletin_error,"bad minute, %d\n",mi); return 20; } if (is_null(ss)){ sprintf (isf_bulletin_error,"missing second\n"); return 20; } if ( ss < 0 || ss > 59 ){ sprintf (isf_bulletin_error,"bad second, %d\n",ss); return 20; } fprintf (fp,"%02d:%02d:%02d",hh,mi,ss); /* Chars 37-40 msec - put blanks here if no msec provided */ if (is_null(msec)){ fprintf (fp," "); } else { if ( msec < 0 || msec > 999 ){ sprintf (isf_bulletin_error,"bad msec, %d\n",msec); return 20; } fprintf (fp,".%03d ",msec); } } /* Chars 42-46: time residual. Char 47: space */ if (is_null(timeres)){ fprintf (fp," "); } else{ if (timeres < -9999 || timeres > 9999 ){ sprintf (isf_bulletin_error,"bad timeres: %f\n",timeres); return 20; } print_float(fp,timeres,5,1); fprintf (fp," "); } /* Chars 48-52: observed azimuth. Char 53: space */ if (is_null(azim)){ fprintf (fp," "); } else{ if (azim < 0 || azim > 360 ){ sprintf (isf_bulletin_error,"bad azim: %f\n",azim); return 20; } fprintf (fp,"%5.1f ",azim); } /* Chars 54-58: azimuth residual. Char 59: space */ if (is_null(azimres)){ fprintf (fp," "); } else{ if (azimres < -360 || azimres > 360 ){ sprintf (isf_bulletin_error,"bad azimres: %f\n",azimres); return 20; } print_float(fp,azimres,5,1); fprintf (fp," "); } /* Chars 60-65: slowness. Char 66: space */ if (is_null(slow)){ fprintf (fp," "); } else{ if (slow < 0 || slow > 999.99 ){ sprintf (isf_bulletin_error,"bad slow: %f\n",slow); return 20; } fprintf (fp,"%6.2f ",slow); } /* Chars 67-72: slowness residual. Char 73: space */ if (is_null(slowres)){ fprintf (fp," "); } else{ if (slowres < -99999 || slowres > 99999 ){ sprintf (isf_bulletin_error,"bad slowres: %f\n",slowres); return 20; } print_float(fp,slowres,6,1); fprintf (fp," "); } /* Char 74: time defining flag */ if (timedef == 'T' || timedef == '_'){ fprintf(fp,"%c",timedef); } else { sprintf (isf_bulletin_error,"bad timedef flag: %c",timedef); return 20; } /* Char 75: azimuth defining flag */ if (azimdef == 'A' || azimdef == '_'){ fprintf(fp,"%c",azimdef); } else { sprintf (isf_bulletin_error,"bad azimdef flag: %c",azimdef); return 20; } /* Char 76: slowness defining flag. Char 77: space. */ if (slowdef == 'S' || slowdef == '_'){ fprintf(fp,"%c ",slowdef); } else { sprintf (isf_bulletin_error,"bad slowdef flag: %c",slowdef); return 20; } /* Chars 78-82: signal-to noise. Char 83: space */ if (is_null(snr)){ fprintf (fp," "); } else{ if (snr < 0 || snr > 999 ){ sprintf (isf_bulletin_error,"bad snr: %f\n",snr); return 20; } fprintf (fp,"%5.1f ",snr); } /* Chars 84-92: amplitude. Char 93: space */ if (is_null(amp)){ fprintf (fp," "); } else{ if (amp < 0 || amp > 9999999.9 ){ sprintf (isf_bulletin_error,"bad amp: %f\n",amp); return 20; } fprintf (fp,"%9.1f ",amp); } /* Chars 94-98: period. Char 99: space */ if (is_null(per)){ fprintf (fp," "); } else{ if (per < 0 || per > 99.99 ){ sprintf (isf_bulletin_error,"bad per: %f\n",per); return 20; } fprintf (fp,"%5.2f ",per); } /* Char 100: picktype. */ if (picktype=='a' || picktype=='m' || picktype=='_'){ fprintf(fp,"%c",picktype); } else { sprintf (isf_bulletin_error,"bad picktype: %c",picktype); return 20; } /* Char 101: sp_fm. */ if (sp_fm=='c' || sp_fm=='d' || sp_fm=='_'){ fprintf(fp,"%c",sp_fm); } else { sprintf (isf_bulletin_error,"bad sp_fm: %c",sp_fm); return 20; } /* Char 102: detchar. Char 103: space. */ if (detchar=='i' || detchar=='e' || detchar=='q' || detchar=='_'){ fprintf(fp,"%c ",detchar); } else { sprintf (isf_bulletin_error,"bad detchar: %c",detchar); return 20; } /* Chars 104-108: magnitude type */ if (magtype[0] == '\0' ){ fprintf (fp,"%*s",ISF_MAGTYPE_LEN,""); } else { if (strlen(magtype) > ISF_MAGTYPE_LEN ){ sprintf (isf_bulletin_error,"magtype too long: %s\n",magtype); return 20; } if (check_whole(magtype)){ sprintf (isf_bulletin_error,"bad magtype: %s\n",magtype); return 20; } fprintf (fp,"%-*s",ISF_MAGTYPE_LEN,magtype); } /* Char 109: magnitude indicator. */ if (magind == ' ' || magind == '<' || magind == '>'){ fprintf(fp,"%c",magind); } else { sprintf (isf_bulletin_error,"bad magind: %c",magind); return 20; } /* Chars 110-113: magnitude. Char 114: space */ if (is_null(mag)){ fprintf (fp," "); } else{ if (mag < 0 || mag > 10 ){ sprintf (isf_bulletin_error,"bad mag: %f\n",mag); return 20; } fprintf (fp,"%4.1f ",mag); } /* Chars 115-122: arrival ID */ if (arrid[0] == '\0' ){ sprintf (isf_bulletin_error,"missing arrid\n"); return 20; } if (strlen(arrid) > ISF_ARRID_LEN ){ sprintf (isf_bulletin_error,"arrid too long: %s\n",arrid); return 20; } if (check_whole(arrid)){ sprintf (isf_bulletin_error,"bad arrid: %s\n",arrid); return 20; } fprintf (fp,"%-*s\n",ISF_ARRID_LEN,arrid); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a phase origin-id comment line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_phase_origid(FILE *fp, char *origid) { char line_type[] = "phase_origid"; /* Chars 1-10: comment start string and space. */ fprintf(fp," (#OrigID "); /* Chars 11-18: origin ID followed by ')'. */ if (origid[0] == '\0'){ sprintf (isf_bulletin_error,"missing origid\n"); return 20; } if (strlen(origid) > ISF_ORIGID_LEN){ sprintf (isf_bulletin_error,"origid too long: %s\n",origid); return 20; } if (check_whole(origid)){ sprintf (isf_bulletin_error,"bad origid: %s\n",origid); return 20; } fprintf(fp,"%-*s)\n",ISF_ORIGID_LEN,origid); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes phase info header complete with preceding blank line. Returns 0 on a successful write. Returns 10 if these lines should not follow the previous line written. On error writes a diagnostic to isf_bulletin_error. */ int write_phase_info_head(FILE *fp) { char line_type[] = "phase_info_head"; char head[] = "Net Chan F Low_F HighF AuthPhas Date eTime wTime eAzim wAzim eSlow wSlow eAmp ePer eMag Author ArrID"; fprintf(fp,"\n%s\n",head); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a phase info block data line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_phase_info(FILE *fp, char *net, char *chan, char filter, float filter_min, float filter_max, char *phase, int yyyy, int mm, int dd, float time_unc, float time_weight, float azim_unc, float azim_weight, float slow_unc, float slow_weight, float amp_unc, float per_unc, float mag_unc, char *author, char *arrid) { char line_type[] = "phase_info"; /* Chars 1-9: network code. Char 10: space. */ if (net[0] == '\0' ){ fprintf (fp,"%*s ",ISF_NET_LEN,""); } else { if (strlen(net) > ISF_NET_LEN ){ sprintf (isf_bulletin_error,"net too long: %s\n",net); return 20; } if (check_whole(net)){ sprintf (isf_bulletin_error,"bad net: %s\n",net); return 20; } fprintf (fp,"%-*s ",ISF_NET_LEN,net); } /* Chars 11-13: channel. Char 14: space. */ if (chan[0] == '\0' ){ fprintf (fp,"%*s ",ISF_CHAN_LEN,""); } else { if (strlen(chan) > ISF_CHAN_LEN ){ sprintf (isf_bulletin_error,"chan too long: %s\n",chan); return 20; } fprintf (fp,"%-*s ",ISF_CHAN_LEN,chan); } /* Char 15: filter. Char 16: space. */ if (filter == '0' || filter == 'C' || filter == ' '){ fprintf (fp,"%c ",filter); } else { sprintf (isf_bulletin_error,"bad filter: %c",filter); return 20; } /* Chars 17-21: minimum filter frequency. Char 22: space. */ if (is_null(filter_min)){ fprintf (fp," "); } else{ if (filter_min < 0 || filter_min > 99999 ){ sprintf (isf_bulletin_error,"bad filter_min: %f\n",filter_min); return 20; } print_float(fp,filter_min,5,2); fprintf (fp," "); } /* Chars 23-27: maximum filter frequency. Char 28: space. */ if (is_null(filter_max)){ fprintf (fp," "); } else{ if (filter_max < 0 || filter_max > 99999 ){ sprintf (isf_bulletin_error,"bad filter_max: %f\n",filter_max); return 20; } print_float(fp,filter_max,5,2); fprintf (fp," "); } /* Chars 29-36: author's phase. Char 37: space. */ if (phase[0] == '\0' ){ fprintf (fp,"%*s ",ISF_PHASE_LEN,""); } else { if (strlen(phase) > ISF_PHASE_LEN ){ sprintf (isf_bulletin_error,"phase too long: %s\n",phase); return 20; } if (check_whole(phase)){ sprintf (isf_bulletin_error,"bad phase: %s\n",phase); return 20; } fprintf (fp,"%-*s ",ISF_PHASE_LEN,phase); } /* Chars 38-47: arrival date. Char 48: space. */ if (is_null(yyyy) && is_null(mm) && is_null(dd)){ fprintf (fp," "); } else{ if (is_null(yyyy)){ sprintf (isf_bulletin_error,"date but no year\n"); return 20; } if ( yyyy < 0 || yyyy > 9999 ){ sprintf (isf_bulletin_error,"bad year: %d\n",yyyy); return 20; } if (is_null(mm)){ sprintf (isf_bulletin_error,"year but no month\n"); return 20; } if ( mm < 0 || mm > 12 ){ sprintf (isf_bulletin_error,"bad month: %d\n",mm); return 20; } if (is_null(dd)){ sprintf (isf_bulletin_error,"year but no day\n"); return 20; } if ( dd < 0 || dd > 31 ){ sprintf (isf_bulletin_error,"bad day: %d\n",dd); return 20; } fprintf (fp,"%04d/%02d/%02d ",yyyy,mm,dd); } /* Chars 49-54: uncertainty in arrival time. Char 55 space. */ if (is_null(time_unc)){ fprintf (fp," "); } else{ if (time_unc < 0 || time_unc > 99.999 ){ sprintf (isf_bulletin_error,"bad time_unc: %f\n",time_unc); return 20; } fprintf (fp,"%6.3f ",time_unc); } /* Chars 56-60: time weight. Char 61 space. */ if (is_null(time_weight)){ fprintf (fp," "); } else{ if (time_weight < 0 || time_weight > 1 ){ sprintf (isf_bulletin_error,"bad time_weight: %f\n",time_weight); return 20; } fprintf (fp,"%5.3f ",time_weight); } /* Chars 62-66: azimuth uncertainty. Char 67 space. */ if (is_null(azim_unc)){ fprintf (fp," "); } else{ if (azim_unc < 0 || azim_unc > 360 ){ sprintf (isf_bulletin_error,"bad azim_unc: %f\n",azim_unc); return 20; } fprintf (fp,"%5.1f ",azim_unc); } /* Chars 68-72: azimuth weight. Char 73 space. */ if (is_null(azim_weight)){ fprintf (fp," "); } else{ if (azim_weight < 0 || azim_weight > 1 ){ sprintf (isf_bulletin_error,"bad azim_weight: %f\n",azim_weight); return 20; } fprintf (fp,"%5.3f ",azim_weight); } /* Chars 74-79: slowness uncertainty. Char 80 space. */ if (is_null(slow_unc)){ fprintf (fp," "); } else{ if (slow_unc < 0 || slow_unc > 9999.9 ){ sprintf (isf_bulletin_error,"bad slow_unc: %f\n",slow_unc); return 20; } fprintf (fp,"%6.1f ",slow_unc); } /* Chars 81-85: slowness weight. Char 86 space. */ if (is_null(slow_weight)){ fprintf (fp," "); } else{ if (slow_weight < 0 || slow_weight > 1 ){ sprintf (isf_bulletin_error,"bad slow_weight: %f\n",slow_weight); return 20; } fprintf (fp,"%5.3f ",slow_weight); } /* Chars 87-95: amplitude unceratinty. Char 96 space. */ if (is_null(amp_unc)){ fprintf (fp," "); } else{ if (amp_unc < 0 || amp_unc > 9999999.9 ){ sprintf (isf_bulletin_error,"bad amp_unc: %f\n",amp_unc); return 20; } fprintf (fp,"%9.1f ",amp_unc); } /* Chars 97-101: period uncertainty. Char 102 space. */ if (is_null(per_unc)){ fprintf (fp," "); } else{ if (per_unc < 0 || per_unc > 99.99 ){ sprintf (isf_bulletin_error,"bad per_unc: %f\n",per_unc); return 20; } fprintf (fp,"%5.2f ",per_unc); } /* Chars 103-105: uncertainty in station magnitude. Char 106 space. */ if (is_null(mag_unc)){ fprintf (fp," "); } else{ if (mag_unc < 0 || mag_unc > 9.9 ){ sprintf (isf_bulletin_error,"bad mag_unc: %f\n",mag_unc); return 20; } fprintf (fp,"%3.1f ",mag_unc); } /* Chars 107-114: author. Char 115: space. */ if (author[0] == '\0' ){ fprintf (fp,"%*s ",ISF_AUTHOR_LEN,""); } else{ if (strlen(author) > ISF_AUTHOR_LEN ){ sprintf (isf_bulletin_error,"author too long: %s\n",author); return 20; } if (check_whole(author)){ sprintf (isf_bulletin_error,"bad author: %s\n",author); return 20; } fprintf (fp,"%-*s ",ISF_AUTHOR_LEN,author); } /* Chars 116-123: arrival ID */ if (arrid[0] == '\0' ){ sprintf (isf_bulletin_error,"missing arrid\n"); return 20; } if (strlen(arrid) > ISF_ARRID_LEN ){ sprintf (isf_bulletin_error,"arrid too long: %s\n",arrid); return 20; } if (check_whole(arrid)){ sprintf (isf_bulletin_error,"bad arrid: %s\n",arrid); return 20; } fprintf (fp,"%-*s\n",ISF_ARRID_LEN,arrid); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a phase measure formatted comment. Writes any number of parameter=value pairs, starting new line if necessary. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_phase_measure(FILE *fp, char **param, char **value, char **error, int numparam) { char line_type[ISF_LINE_LEN]; int i,len,space_left; /* Phase measure lines can be in either phase or phase info blocks. */ if ( strcmp(isf_prev_line_type,"phase")==0 || strcmp(isf_prev_line_type,"phase_com")==0 ){ strcpy(line_type,"phase_com"); } else{ strcpy(line_type,"phase_info_com"); } fprintf (fp," (#MEASURE"); space_left = ISF_COMM_LEN; for (i=0;i ISF_COMM_LEN){ sprintf (isf_bulletin_error,"%s=%s too long",param[i],value[i]); return 20; } if (space_left < len){ fprintf (fp,")\n (#MEASURE"); space_left = ISF_COMM_LEN; } fprintf (fp," %s=%s",param[i],value[i]); if (error[i][0] != '\0'){ fprintf (fp,"+%s",error[i]); } space_left -= len; } fprintf (fp,")\n"); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a minimum phase range line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_phase_min(FILE *fp, float timeoffset, float azoffset, float slowoffset, float ampoffset, float peroffset, float magoffset) { char line_type[] = "phase_info_com"; int i; /* Chars 1-6: comment format string. */ fprintf(fp," (#MIN"); /* Chars 7-47: spaces. */ for (i=6;i<47;i++) fprintf(fp," "); /* Chars 48-54: time offset.*/ if (is_null(timeoffset)){ fprintf (fp," "); } else{ if (timeoffset < -99.999 || timeoffset > 0 ){ sprintf (isf_bulletin_error,"bad timeoffset: %f\n",timeoffset); return 20; } fprintf (fp,"%7.3f",timeoffset); } /* Chars 55-60: spaces. */ for (i=54;i<60;i++) fprintf(fp," "); /* Chars 61-66: azimuth offset. */ if (is_null(azoffset)){ fprintf (fp," "); } else{ if (azoffset < -360 || azoffset > 0 ){ sprintf (isf_bulletin_error,"bad azoffset: %f\n",azoffset); return 20; } fprintf (fp,"%6.1f",azoffset); } /* Chars 67-72: spaces. */ for (i=66;i<72;i++) fprintf(fp," "); /* Chars 73-79: slowness offset. */ if (is_null(slowoffset)){ fprintf (fp," "); } else{ if (slowoffset < -9999.9 || slowoffset > 0 ){ sprintf (isf_bulletin_error,"bad slowoffset: %f\n",slowoffset); return 20; } fprintf (fp,"%7.1f",slowoffset); } /* Chars 80-85: spaces. */ for (i=79;i<85;i++) fprintf(fp," "); /* Chars 86-95: amplitude offset. */ if (is_null(ampoffset)){ fprintf (fp," "); } else{ if (ampoffset < -9999999.9 || ampoffset > 0 ){ sprintf (isf_bulletin_error,"bad slowoffset: %f\n",ampoffset); return 20; } fprintf (fp,"%10.1f",ampoffset); } /* Chars 96-101: period offset. */ if (is_null(peroffset)){ fprintf (fp," "); } else{ if (peroffset < -999.9 || peroffset > 0 ){ sprintf (isf_bulletin_error,"bad peroffset: %f\n",peroffset); return 20; } fprintf (fp,"%6.1f",peroffset); } /* Chars 102-105: magnitude offset. */ if (is_null(magoffset)){ fprintf (fp," )\n"); } else{ if (magoffset < -9.9 || magoffset > 0 ){ sprintf (isf_bulletin_error,"bad magoffset: %f\n",magoffset); return 20; } fprintf (fp,"%4.1f)\n",magoffset); } /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a maximum phase range line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_phase_max(FILE *fp, float timeoffset, float azoffset, float slowoffset, float ampoffset, float peroffset, float magoffset) { char line_type[] = "phase_info_com"; int i; /* Chars 1-6: comment format string. */ fprintf(fp," (#MAX"); /* Chars 7-47: spaces. */ for (i=6;i<47;i++) fprintf(fp," "); /* Chars 48-54: time offset.*/ if (is_null(timeoffset)){ fprintf (fp," "); } else{ if (timeoffset < 0 || timeoffset > 99.999 ){ sprintf (isf_bulletin_error,"bad timeoffset: %f\n",timeoffset); return 20; } fprintf (fp,"%7.3f",timeoffset); } /* Chars 55-60: spaces. */ for (i=54;i<60;i++) fprintf(fp," "); /* Chars 61-66: azimuth offset. */ if (is_null(azoffset)){ fprintf (fp," "); } else{ if (azoffset < 0 || azoffset > 360 ){ sprintf (isf_bulletin_error,"bad azoffset: %f\n",azoffset); return 20; } fprintf (fp,"%6.1f",azoffset); } /* Chars 67-72: spaces. */ for (i=66;i<72;i++) fprintf(fp," "); /* Chars 73-79: slowness offset. */ if (is_null(slowoffset)){ fprintf (fp," "); } else{ if (slowoffset < 0 || slowoffset > 9999.9 ){ sprintf (isf_bulletin_error,"bad slowoffset: %f\n",slowoffset); return 20; } fprintf (fp,"%7.1f",slowoffset); } /* Chars 80-85: spaces. */ for (i=79;i<85;i++) fprintf(fp," "); /* Chars 86-95: amplitude offset. */ if (is_null(ampoffset)){ fprintf (fp," "); } else{ if (ampoffset < 0 || ampoffset > 9999999.9 ){ sprintf (isf_bulletin_error,"bad slowoffset: %f\n",ampoffset); return 20; } fprintf (fp,"%10.1f",ampoffset); } /* Chars 96-101: period offset. */ if (is_null(peroffset)){ fprintf (fp," "); } else{ if (peroffset < 0 || peroffset > 999.9){ sprintf (isf_bulletin_error,"bad peroffset: %f\n",peroffset); return 20; } fprintf (fp,"%6.1f",peroffset); } /* Chars 102-105: magnitude offset. */ if (is_null(magoffset)){ fprintf (fp," )\n"); } else{ if (magoffset < 0 || magoffset > 9.9 ){ sprintf (isf_bulletin_error,"bad magoffset: %f\n",magoffset); return 20; } fprintf (fp,"%4.1f)\n",magoffset); } /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a phase correction line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_phase_correc(FILE *fp, float timecorr, float azcorr, float slowcorr, float ampcorr, float percorr, float magcorr ) { char line_type[] = "phase_info_com"; int i; /* Chars 1-8: comment format string. */ fprintf (fp," (#COREC"); /* Chars 9-47: spaces. */ for (i=8;i<47;i++) fprintf(fp," "); /* Chars 48-54: time correction. */ if (is_null(timecorr)){ fprintf (fp," "); } else{ if (timecorr < -99.999 || timecorr > 99.999){ sprintf (isf_bulletin_error,"bad timecorr: %f\n",timecorr); return 20; } fprintf (fp,"%7.3f",timecorr); } /* Chars 55-60: spaces. */ for (i=54;i<60;i++) fprintf(fp," "); /* Chars 61-66: azimuth correction. */ if (is_null(azcorr)){ fprintf (fp," "); } else{ if (azcorr < -360 || azcorr > 360){ sprintf (isf_bulletin_error,"bad azcorr: %f\n",azcorr); return 20; } fprintf (fp,"%6.1f",azcorr); } /* Chars 67-72: spaces. */ for (i=66;i<72;i++) fprintf(fp," "); /* Chars 73-79: slowness correction. */ if (is_null(slowcorr)){ fprintf (fp," "); } else{ if (slowcorr < -9999.9 || slowcorr > 9999.9){ sprintf (isf_bulletin_error,"bad slowcorr: %f\n",slowcorr); return 20; } fprintf (fp,"%7.1f",slowcorr); } /* Chars 80-85: spaces. */ for (i=79;i<85;i++) fprintf(fp," "); /* Chars 86-95: amplitude correction. */ if (is_null(ampcorr)){ fprintf (fp," "); } else{ if (ampcorr < -9999999.9 || ampcorr > 9999999.9){ sprintf (isf_bulletin_error,"bad ampcorr: %f\n",ampcorr); return 20; } fprintf (fp,"%10.1f",ampcorr); } /* Chars 96-101: period correction. */ if (is_null(percorr)){ fprintf (fp," "); } else{ if (percorr < -999.9 || percorr > 999.9){ sprintf (isf_bulletin_error,"bad percorr: %f\n",percorr); return 20; } fprintf (fp,"%6.1f",percorr); } /* Chars 102-106: magnitude correction. */ if (is_null(magcorr)){ fprintf (fp," )\n"); } else{ if (magcorr < -9.99 || magcorr > 9.99){ sprintf (isf_bulletin_error,"bad magcorr: %f\n",magcorr); return 20; } fprintf (fp,"%5.2f)\n",magcorr); } if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes an original phase data line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_phase_original(FILE *fp, char *chan, char *sta, int yyyy, int mm, int dd, int hh, int mi, int ss, int msec, float azim, float slow, float amp, float per, float mag) { char line_type[] = "phase_info_com"; int i; /* Chars 1-10: comment format string. */ fprintf (fp," (#ORIG "); /* Chars 11-13: original channel. Char 14: space. */ if (chan[0]=='\0'){ fprintf (fp,"%*s ",ISF_CHAN_LEN,""); } else{ if (strlen(chan) != ISF_CHAN_LEN ){ sprintf (isf_bulletin_error,"chan wrong length: %s\n",chan); return 20; } fprintf (fp,"%*s ",ISF_CHAN_LEN,chan); } /* Chars 15-19: original station code. Char 20-37: spaces.*/ /* Format gives 8 chars for sta but sta can only be 5 chars long in IMS. */ if (sta[0]=='\0'){ fprintf (fp,"%*s",23,""); } else{ if (strlen(sta) > ISF_STA_LEN ){ sprintf (isf_bulletin_error,"sta too long: %s\n",sta); return 20; } if (check_whole(sta)){ sprintf (isf_bulletin_error,"bad sta: %s\n",sta); return 20; } fprintf (fp,"%-*s%*s",ISF_STA_LEN,sta,23-ISF_STA_LEN,""); } /* Chars 38-60: arrival date and time. */ /* Chars 38-47: date. Char 48: space. */ if (is_null(yyyy) && is_null(mm) && is_null(dd)){ for (i=37;i<48;i++) fprintf(fp," "); } else{ if (is_null(yyyy)){ sprintf (isf_bulletin_error,"date without year\n"); return 20; } if ( yyyy < 0 || yyyy > 9999 ){ sprintf (isf_bulletin_error,"bad year: %d\n",yyyy); return 20; } if (is_null(mm)){ sprintf (isf_bulletin_error,"date without month\n"); return 20; } if ( mm < 0 || mm > 12 ){ sprintf (isf_bulletin_error,"bad month: %d\n",mm); return 20; } if (is_null(dd)){ sprintf (isf_bulletin_error,"date without day\n"); return 20; } if ( dd < 0 || dd > 31 ){ sprintf (isf_bulletin_error,"bad day: %d",dd); return 20; } fprintf (fp,"%04d/%02d/%02d ",yyyy,mm,dd); } /* Chars 49-60: time. Char 61: space */ if (is_null(hh) && is_null(mi) && is_null(ss)){ for (i=48;i<61;i++) fprintf(fp," "); } else { if (is_null(hh)){ sprintf (isf_bulletin_error,"time without hour\n"); return 20; } if ( hh < 0 || hh > 23 ){ sprintf (isf_bulletin_error,"bad hour: %d\n",hh); return 20; } if (is_null(mi)){ sprintf (isf_bulletin_error,"time without minute\n"); return 20; } if ( mi < 0 || mi > 59 ){ sprintf (isf_bulletin_error,"bad minute: %d\n",mi); return 20; } if (is_null(ss)){ sprintf (isf_bulletin_error,"time without second\n"); return 20; } if ( ss < 0 || ss > 59 ){ sprintf (isf_bulletin_error,"bad second: %d\n",ss); return 20; } fprintf (fp,"%02d:%02d:%02d",hh,mi,ss); /* Chars 57-60 msec - put blanks here if no msec provided. */ if (is_null(msec)){ fprintf (fp," "); } else { if ( msec < 0 || msec > 999 ){ sprintf (isf_bulletin_error,"bad msec: %d\n",msec); return 20; } fprintf (fp,".%03d ",msec); } } /* Chars 62-66: original azimuth.*/ if (is_null(azim)){ fprintf (fp," "); } else{ if (azim < 0 || azim > 360){ sprintf (isf_bulletin_error,"bad azim: %f\n",azim); return 20; } fprintf (fp,"%5.1f",azim); } /* Char 67-73: must be a space. */ for (i=66;i<73;i++) fprintf(fp," "); /* Chars 74-79: original slowness. */ if (is_null(slow)){ fprintf (fp," "); } else{ if (slow < 0 || slow > 9999.9){ sprintf (isf_bulletin_error,"bad slow: %f\n",slow); return 20; } fprintf (fp,"%6.1f",slow); } /* Char 80-86: must be a space. */ for (i=79;i<86;i++) fprintf(fp," "); /* Chars 87-95: original amplitude. Char 96: space. */ if (is_null(amp)){ fprintf (fp," "); } else{ if (amp < 0 || amp > 9999999.9){ sprintf (isf_bulletin_error,"bad amp: %f\n",amp); return 20; } fprintf (fp,"%9.1f ",amp); } /* Chars 97-101: original period. Char 102: space. */ if (is_null(per)){ fprintf (fp," "); } else{ if (per < 0 || per > 99.99){ sprintf (isf_bulletin_error,"bad per: %f\n",per); return 20; } fprintf (fp,"%5.2f ",per); } /* Chars 103-105: original station magnitude. */ if (is_null(mag)){ fprintf (fp," )\n"); } else{ if (mag < 0 || mag > 99.99){ sprintf (isf_bulletin_error,"bad mag: %f\n",mag); return 20; } fprintf (fp,"%3.1f)\n",mag); } /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes a plain IMS comment. Takes string as its argument, cuts it into lines of less than the maximium allowed length and adds brackets to the start and end of each line. Returns 0 on a successful write. Returns 10 if this line should not follow the previous line written. Returns 20 if any of the variables passed are unsuitable for writing. On error writes a diagnostic to isf_bulletin_error. */ int write_comment(FILE *fp, char *comment) { int len,i; char substr[ISF_LINE_LEN]; char line_type[ISF_LINE_LEN]; /* line_type depends on previous line_type. */ if (strcmp(isf_prev_line_type,"origin")==0 || strcmp(isf_prev_line_type,"origin_com")==0 || strcmp(isf_prev_line_type,"axes")==0 || strcmp(isf_prev_line_type,"axes_err")==0 || strcmp(isf_prev_line_type,"fault_plane")==0 || strcmp(isf_prev_line_type,"netmag")==0 || strcmp(isf_prev_line_type,"momten")==0 ) { strcpy(line_type,"origin_com"); } else if ( strcmp(isf_prev_line_type,"effects")==0 || strcmp(isf_prev_line_type,"effects_com")==0 ){ strcpy(line_type,"effects_com"); } else if ( strcmp(isf_prev_line_type,"phase")==0 || strcmp(isf_prev_line_type,"phase_com")==0 ){ strcpy(line_type,"phase_com"); } else if ( strcmp(isf_prev_line_type,"phase_info")==0 || strcmp(isf_prev_line_type,"phase_info_com")==0 ){ strcpy(line_type,"phase_info_com"); } else { strcpy(line_type,"comment"); } len = strlen(comment); /* Start continuation lines with a space inside the bracket. */ fprintf(fp," ("); while (len > ISF_LINE_LEN){ for (i=ISF_LINE_LEN; i>0; i--){ if (comment[i] == ' ') break; } partline(substr,comment,0,i); fprintf(fp,"%s)\n ( ",substr); partline(substr,comment,i,0); strcpy(comment,substr); len = len - i; } fprintf(fp,"%s)\n",comment); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; } /* Writes STOP line with a preceding blank line */ int write_stop(FILE *fp) { char line_type[] = "stop"; fprintf(fp,"\nSTOP\n"); /* Check that this line's type should follow the previous line's type. */ if (check_prev_line_type(line_type)){ return 10; } return 0; }