00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <time.h>
00026 #include <ctype.h>
00027 #include <math.h>
00028 #include <errno.h>
00029 #include <unistd.h>
00030 #include <string.h>
00031 #include <sys/types.h>
00032 #include <sys/stat.h>
00033 #include <fcntl.h>
00034 #include <dirent.h>
00035 #include <assert.h>
00036 #include <signal.h>
00037
00038 #include "common.h"
00039
00040 #define MAX_SENSOR_NUMBER 300
00041
00042 struct SensorType {
00043 char name[16];
00044 char type[16];
00045 char band;
00046 float cornerPeriod;
00047 };
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 struct SensorType sensorEntry[MAX_SENSOR_NUMBER] =
00075 {
00076 { "STS1", "LP", 0, -1. },
00077 { "STS2", "LP", 0, -1. },
00078 { "STS2L", "LP", 0, -1. },
00079 { "STS1P", "MP", 0, -1. },
00080 { "STS2P", "MP", 0, -1. },
00081 { "STS2LP", "MP", 0, -1. },
00082
00083 { "CMG5", "ACC", 0, -1. },
00084 { "CMG5HP", "ACC", 0, -1. },
00085 { "CMG3T", "LP", 0, -1. },
00086 { "CMG3E", "LP", 0, -1. },
00087 { "CMG40T", "LP", 0, -1. },
00088
00089 { "EST", "ACC", 0, -1. },
00090
00091 { "LE3D1S", "CP", 0, -1. },
00092 { "LE3D5S", "CP", 0, -1. },
00093 { "LE3D20S", "LP", 0, -1. },
00094
00095 { "L22", "CP", 0, -1. },
00096 { "L4C", "CP", 0, -1. },
00097
00098 { "SDJ", "CP", 0, -1. },
00099 { "SDJ5S", "CP", 0, -1. },
00100
00101
00102 { "", "", 0, -1. }
00103 };
00104
00105 struct ChannelType {
00106 struct StationType *station;
00107 int number;
00108 char location[32];
00109 char sensor[32];
00110 char componnent[32];
00111 float azimuth;
00112 float incidence;
00113 };
00114
00115 struct StationType {
00116 char name[32];
00117 char network[32];
00118 float lat;
00119 float lon;
00120 float elev;
00121 float dep;
00122 time_t from;
00123 time_t to;
00124 struct ChannelType channel[MAX_OSIRIS_CHANNEL];
00125 struct StationType *next;
00126 };
00127
00128 char **tdbPaths=NULL;
00129
00130 struct StationType *tdbStation=NULL;
00131
00132 char *confKeyWord[] = { "dt", "dft", "tc", "stations", NULL };
00133
00136 int ReadSensorList(void)
00137 {
00138 FILE *f;
00139 char line[128];
00140 int i=0;
00141 f=fopen(TDBPath(TDB_PATH_SENSORLIST,"none"),"rt");
00142 if (f)
00143 {
00144 PrintLog("reading '%s'\n",TDBPath(TDB_PATH_SENSORLIST,"none"));
00145 memset(sensorEntry,0,MAX_SENSOR_NUMBER*sizeof(struct SensorType));
00146 while (!feof(f))
00147 {
00148 char field[12];
00149 sensorEntry[i].cornerPeriod=-1.;
00150 fgets(line, 128, f);
00151 if (line[0]=='#')
00152 {
00153 continue;
00154 }
00155 if (2!=sscanf(line,"%s %s",sensorEntry[i].name,field))
00156 {
00157 continue;
00158 }
00159 if (strlen(field)==1)
00160 {
00161 sensorEntry[i].band=field[0];
00162 }
00163 else
00164 {
00165 float c;
00166 if (1==sscanf(field,"%f",&c))
00167 {
00168 sensorEntry[i].cornerPeriod=c;
00169 }
00170 else
00171 {
00172 strcpy(sensorEntry[i].type,field);
00173 }
00174 }
00175 PrintDebug("%-010s %-06s '%01c' %5.1f\n",
00176 sensorEntry[i].name,
00177 sensorEntry[i].type,
00178 sensorEntry[i].band,
00179 sensorEntry[i].cornerPeriod);
00180 i++;
00181 }
00182 fclose(f);
00183 }
00184 return(0);
00185 }
00186
00190 char *ChannelName(char *sensor, float s)
00191 {
00192
00193 struct { char code; float minS, maxS, minP, maxP; } thr[] =
00194 {
00195 { 'F', 1000., 5000., 10., 1.e9 },
00196 { 'G', 1000., 5000., -1., 10.0 },
00197 { 'D', 250., 1000., -1., 10.0 },
00198 { 'C', 250., 1000., 10., 1.e9 },
00199 { 'E', 80., 250., -1., 10.0 },
00200 { 'S', 10., 80., -1., 10.0 },
00201 { 'H', 80., 250., 10., 1.e9 },
00202 { 'B', 10., 80., 10., 1.e9 },
00203 { 'M', 1.0001, 10., -1., 1.e9 },
00204 { 'L', 0.9,1.0001, -1., 1.e9 },
00205 { 'M', 0.01, 0.9, -1., 1.e9 },
00206 { 0 , 0.0, 0.0, 0.0, 0.0 },
00207
00208 };
00209 static char channel[3];
00210 int is,j;
00211 float f;
00212 channel[0]=' ';
00213 channel[1]=' ';
00214 channel[2]=0;
00215
00216 for (is=0; is<MAX_SENSOR_NUMBER; is++)
00217 {
00218
00219 if (sensorEntry[is].name==NULL)
00220 {
00221 return(NULL);
00222 }
00223
00224 if (0==strcmp(sensor,sensorEntry[is].name))
00225 {
00226 break;
00227 }
00228 }
00229
00230
00231 f=sensorEntry[is].cornerPeriod;
00232
00233 if (sensorEntry[is].type[0]!=0)
00234 {
00235
00236
00237 if (0==strcmp(sensorEntry[is].type,"LP"))
00238 {
00239 f=20.;
00240 }
00241 else
00242 {
00243 f=1.;
00244 }
00245 }
00246
00247
00248 for (j=0; thr[j].code; j++)
00249 {
00250 if ( (s>=thr[j].minS)&&(s<thr[j].maxS) && (f>=thr[j].minP)&&(f<thr[j].maxP) )
00251 {
00252 channel[0]=thr[j].code;
00253 break;
00254 }
00255 }
00256 if (channel[0]==' ')
00257 {
00258 PrintError("cannot determine band code for 'sr=%.1fHz, cp=%.1f (type='%s')\n",
00259 s,f,sensorEntry[is].type);
00260 }
00261
00262
00263 if (sensorEntry[is].band!=0)
00264 {
00265 channel[1]=sensorEntry[is].band;
00266 }
00267 else
00268 {
00269
00270 channel[1]='H';
00271
00272 if (
00273 (0==strcmp(sensorEntry[is].name,"STS1P"))||
00274 (0==strcmp(sensorEntry[is].name,"STS2P"))||
00275 (0==strcmp(sensorEntry[is].name,"STS2LP"))
00276 )
00277 {
00278 channel[1]='M';
00279 }
00280
00281 if (0==strcmp(sensorEntry[is].type,"ACC"))
00282 {
00283 channel[1]='N';
00284 }
00285 }
00286 if (NULL==strchr("HLGMN",channel[1]))
00287 {
00288 PrintError("illegal instrument code '%c'\n",channel[1]);
00289 return(NULL);
00290 }
00291
00292 return(channel);
00293 }
00294
00299 char * TDBPath(int p, char * s)
00300 {
00301 static char out[256];
00302 if ((strlen(tdbName)==0)||(s==NULL))
00303 {
00304 return(".");
00305 }
00306 if ((p>=TDB_PATH_LAST)||(p<0))
00307 {
00308 PrintError("unknown TDBPath request: %d\n",p);
00309 return(".");
00310 }
00311 if (p==TDB_PATH_SENSORLIST)
00312 {
00313 return(strcpy(out,tdbPaths[p]));
00314 }
00315 strcat(strcat(strcpy(out,tdbPaths[p]),"/"),s);
00316 mkdir(out,0777);
00317 return(out);
00318 }
00319
00320 void PrintStation(struct StationType *s)
00321 {
00322 int i;
00323 PrintDebug("%6s\n",s->name);
00324 PrintDebug(" start: %s\n",time2str(s->from));
00325 PrintDebug(" end: %s\n",time2str(s->to));
00326 PrintDebug(" location: %.3f %.3f %.1f %.1f\n",s->lat, s->lon, s->elev, s->dep);
00327 for (i=0; i<MAX_OSIRIS_CHANNEL; i++)
00328 {
00329 if (s->channel[i].number>=0)
00330 {
00331 PrintDebug(" channel %2d : %6s %2s %6.1f %6.1f\n",
00332 s->channel[i].number,
00333 s->channel[i].sensor,
00334 s->channel[i].componnent,
00335 s->channel[i].azimuth,
00336 s->channel[i].incidence);
00337 }
00338 }
00339 }
00340
00341 void TDBAbortParsing(char *s, char *fn)
00342 {
00343 char *couldNotParse="could not parse station file";
00344 PrintError("%s '%s/%s'%s %s\n",couldNotParse,
00345 tdbPaths[TDB_PATH_STATIONS],
00346 fn,s?":":"",s?s:"");
00347 exit(1);
00348 }
00349
00352 int TDBInit(void)
00353 {
00354 int i;
00355 FILE *f;
00356 char *conf;
00357 struct dirent **file=NULL;
00358 int nfiles;
00359 char *p;
00360 char line[129];
00361 char tmp[129];
00362 char kw[129];
00363
00364 struct StationType *cur;
00365 struct StationType *new;
00366
00367
00368 fileNameOptions|=ADD_LOCATION_CODE|ADD_CHANNEL_CODE|ADD_NETWORK_CODE;
00369
00370
00371 if (tdbStation!=NULL) return(0);
00372
00373
00374 tdbPaths=(char **)malloc(TDB_PATH_LAST*sizeof(char *));
00375 for (i=0; i<TDB_PATH_LAST; i++)
00376 {
00377 tdbPaths[i]=malloc(256*sizeof(char));
00378 strcpy(tdbPaths[i],".");
00379 }
00380
00381 if (tdbName[0]==0)
00382 {
00383 return(0);
00384 }
00385 PrintLog("reading titan database...\n");
00386
00387
00388 conf=MyGetenv("RTITAN2_CONF");
00389 if (conf==NULL)
00390 {
00391 conf=MyGetenv("CVTIT_CONF");
00392 if (conf!=NULL)
00393 {
00394 PrintLog("using CVTIT_CONF=%s\n",conf);
00395 }
00396 }
00397 else
00398 {
00399 PrintLog("using RTITAN2_CONF=%s\n",conf);
00400 }
00401 if (conf==NULL)
00402 {
00403 PrintError("no RTITAN2_CONF/CVTIT_CONF defined, cannot load database\n");
00404 exit(1);
00405 }
00406
00407 f=fopen(conf,"rt");
00408 if (!f)
00409 {
00410 PrintError("unable to read %s: %m\n",conf);
00411 exit(1);
00412 }
00413
00414 while (!feof(f))
00415 {
00416 #define DO_COMPARISON_KW(__a,__i) \
00417 if (0==strcmp(strcat(strcat(strcpy(tmp,tdbName),"_"),__a),kw)) \
00418 { \
00419 if (1!=sscanf(line,"%*s %s",tdbPaths[__i])) \
00420 { \
00421 PrintError("error parsing %s for keyword '%s'\n", \
00422 conf,kw); \
00423 exit(0); \
00424 } \
00425 }
00426
00427 fgets(line, 128, f);
00428
00429 sscanf(line,"%s",kw);
00430
00431 if (kw[0]=='#') continue;
00432
00433 for (i=0; confKeyWord[i]; i++)
00434 {
00435 DO_COMPARISON_KW(confKeyWord[i],i);
00436 }
00437
00438 }
00439
00440 fclose(f);
00441
00442 for (i=0; i<TDB_PATH_LAST; i++)
00443 {
00444 PrintDebug("%s: %s\n",confKeyWord[i],tdbPaths[i]);
00445 }
00446
00447
00448 if (strcmp(tdbPaths[TDB_PATH_STATIONS],".")==0)
00449 {
00450 PrintError("%s_stations not defined in %s\n",tdbName,conf);
00451 exit(1);
00452 }
00453
00454
00455 nfiles=__scandir(tdbPaths[TDB_PATH_STATIONS],&file,NULL,NULL);
00456
00457 for (i=0; i<nfiles; i++)
00458 {
00459
00460 if (file[i]->d_name[0]=='.') continue;
00461
00462 sprintf(tmp,"%s/%s",tdbPaths[TDB_PATH_STATIONS],file[i]->d_name);
00463 PrintDebug("reading %s\n",tmp);
00464 f=fopen(tmp,"rt");
00465 if (!f)
00466 {
00467 PrintError("%s: %m\n",tmp);
00468 continue;
00469 }
00470
00471 while (!feof(f))
00472 {
00473 struct StationType s;
00474 struct ChannelType c;
00475 char tfrom[32],tto[32];
00476 double tt;
00477 char location[32];
00478 int ii;
00479
00480 do {
00481 fgets(line, 128, f);
00482 kw[0]=0;
00483 sscanf(line,"%s",kw);
00484 } while ((!feof(f))&&(0!=strcasecmp(kw,"begin_station")));
00485 if (feof(f)) break;
00486
00487
00488 memset(&s,0,sizeof(s));
00489 for (ii=0; ii<MAX_OSIRIS_CHANNEL; ii++)
00490 {
00491 s.channel[ii].number=-1;
00492 }
00493 location[0]=0;
00494
00495
00496 if (4!=sscanf(line,"%s %s %s %s",kw,s.name,tfrom,tto))
00497 {
00498 TDBAbortParsing("'begin_station' syntax error",file[i]->d_name);
00499 }
00500 if (str2time(tfrom,&tt)<1)
00501 {
00502 TDBAbortParsing("start time parsing error",file[i]->d_name);
00503 }
00504 s.from=(time_t)tt;
00505 if (str2time(tto,&tt)<1)
00506 {
00507 TDBAbortParsing("end time parsing error",file[i]->d_name);
00508 }
00509 s.to=(time_t)tt;
00510
00511 do
00512 {
00513 int ok=0;
00514
00515 fgets(line, 128, f);
00516 kw[0]=0;
00517 sscanf(line,"%s",kw);
00518 if (kw[0]=='#') continue;
00519
00520 if (0==strcasecmp(kw,"end_station"))
00521 {
00522
00523 new=(struct StationType *)malloc(sizeof(struct StationType));
00524
00525 memcpy(new,&s,sizeof(s));
00526 new->next=NULL;
00527
00528 if (tdbStation==NULL)
00529 {
00530
00531 tdbStation=new;
00532
00533 }
00534 else
00535 {
00536
00537 for (cur=tdbStation; cur->next; cur=cur->next) ;
00538
00539 cur->next=new;
00540
00541 }
00542 ok=1;
00543 }
00544
00545
00546 if (0==strcasecmp(kw,"network"))
00547 {
00548 ok=1;
00549 if (2!=sscanf(line,"%s %s",kw,s.network))
00550 {
00551 TDBAbortParsing("'network' parsing error",file[i]->d_name);
00552 }
00553 }
00554
00555 if (0==strcasecmp(kw,"coordinates"))
00556 {
00557 ok=1;
00558 sscanf(line,"%*s %s",kw);
00559
00560 if (0==strncmp("location=",kw,strlen("location=")))
00561 {
00562
00563 if (1!=sscanf(kw+strlen("location="),"%s",location))
00564 {
00565 TDBAbortParsing("'coordinates location=' parsing error",file[i]->d_name);
00566 }
00567 if (5!=sscanf(line,"%s %*s %f %f %f %f",
00568 kw,&(s.lat),&(s.lon),&(s.elev),&(s.dep)))
00569 {
00570 TDBAbortParsing("'coordinates (location)' parsing error",file[i]->d_name);
00571 }
00572
00573 }
00574 else
00575 {
00576 location[0]=0;
00577
00578 if (5!=sscanf(line,"%s %f %f %f %f",
00579 kw,&(s.lat),&(s.lon),&(s.elev),&(s.dep)))
00580 {
00581 TDBAbortParsing("'coordinates' parsing error",file[i]->d_name);
00582 }
00583
00584 }
00585 }
00586
00587 memset(&c,0,sizeof(c));
00588 strcpy(c.location,location);
00589 c.number=-1;
00590
00591 if (0==strcasecmp(kw,"chan"))
00592 {
00593 ok=1;
00594
00595 if (1!=sscanf(line,"%*s %*s %s",kw))
00596 {
00597 TDBAbortParsing("'chan' parsing error",file[i]->d_name);
00598 }
00599 if (0==strcasecmp(kw,"comp"))
00600 {
00601 int chan,comp;
00602 if (6!=sscanf(line,"%*s %d %*s %d %s %s %f %f",
00603 &chan,&comp,c.sensor,
00604 c.componnent,
00605 &(c.azimuth),&(c.incidence)))
00606 {
00607 TDBAbortParsing("'comp' parsing error",file[i]->d_name);
00608 }
00609 c.number=3*chan+comp;
00610 if (c.number<0) {
00611 TDBAbortParsing("invalid channel index",file[i]->d_name);
00612 }
00613 }
00614 else
00615 {
00616 TDBAbortParsing("'chan' found but no 'comp' defined",file[i]->d_name);
00617 }
00618 }
00619
00620 if (0==strcasecmp(kw,"channel"))
00621 {
00622 ok=1;
00623 if (5!=sscanf(line,"%*s %d %s %s %f %f",
00624 &(c.number),c.sensor,
00625 c.componnent,
00626 &(c.azimuth),&(c.incidence)))
00627 {
00628 TDBAbortParsing("'channel' parsing error",file[i]->d_name);
00629 }
00630 if (c.number<0)
00631 {
00632 TDBAbortParsing("invalid channel index",file[i]->d_name);
00633 }
00634 }
00635
00636
00637
00638 if ((c.number>=0)&&(c.number>=MAX_OSIRIS_CHANNEL))
00639 {
00640 TDBAbortParsing("invalid channel index",file[i]->d_name);
00641 }
00642
00643
00644 if (c.number>=0)
00645 {
00646
00647 if (s.channel[c.number].sensor[0]!=0)
00648 {
00649 TDBAbortParsing("same channel index defined twice",file[i]->d_name);
00650 }
00651 memcpy(&(s.channel[c.number]),&c,sizeof(c));
00652 }
00653
00654
00655 if (ok==0)
00656 {
00657 TDBAbortParsing("unknown keyword found",file[i]->d_name);
00658 }
00659
00660 } while ((!feof(f))&&(0!=strcasecmp(kw,"end_station")));
00661
00662 }
00663
00664 fclose(f);
00665
00666 }
00667
00668
00669 if (tdbStation==NULL)
00670 {
00671 PrintError("no station found for the requested database\n");
00672 exit(-1);
00673 }
00674
00675 for (cur=tdbStation; cur; cur=cur->next)
00676 {
00677 for (i=0; i<MAX_OSIRIS_CHANNEL; i++)
00678 {
00679 cur->channel[i].station=cur;
00680 }
00681 PrintStation(cur);
00682 }
00683
00684 p=strrchr(conf,'/');
00685 if (p==NULL)
00686 {
00687 strcpy(tdbPaths[TDB_PATH_SENSORLIST],"sensor_list");
00688 }
00689 else
00690 {
00691 strcpy(tdbPaths[TDB_PATH_SENSORLIST],conf);
00692 p=strrchr(tdbPaths[TDB_PATH_SENSORLIST],'/');
00693 strcpy(p+1,"sensor_list");
00694 }
00695 ReadSensorList();
00696 return(0);
00697 }
00698
00704 struct ChannelType *TDBGetChannel(char *sta, int channel, time_t when)
00705 {
00706 struct StationType *cur;
00707
00708 for (cur=tdbStation; cur; cur=cur->next)
00709 {
00710 if (
00711 (0==strcmp(sta,cur->name))&&
00712 (when<cur->to)&&(when>cur->from)&&
00713 (cur->channel[channel].number>=0)
00714 )
00715 {
00716 return(&(cur->channel[channel]));
00717 }
00718 }
00719 return(NULL);
00720 }
00721
00725 int TDBUpdateHeader(struct InfoHeaderType *h)
00726 {
00727 struct ChannelType *c;
00728
00729 if (tdbStation==NULL) return(0);
00730
00731 c=TDBGetChannel(h->station, h->ch, h->correctedTime);
00732
00733 if (c==NULL)
00734 {
00735
00736 PrintError("no information could be found for station '%s', channel %d, time: %.23s\n",
00737 h->station,h->ch,time2str(h->correctedTime));
00738 return(-1);
00739
00740 }
00741 else
00742 {
00743 char *tmps;
00744 PrintStation(c->station);
00745
00746 tmps=ChannelName(c->sensor,(float)h->sr.base/(float)h->sr.div);
00747 if (tmps==NULL)
00748 {
00749 return(-1);
00750 }
00751 PrintDebug("updating with channel %d\n",h->ch);
00752 PrintStation(c->station);
00753 strcpy(h->channel,tmps);
00754 strcat(h->channel,c->componnent);
00755 strcpy(h->location,c->location);
00756 strcpy(h->network,c->station->network);
00757 return(0);
00758
00759 }
00760 return(-1);
00761 }