00001 #ifndef _ENSEMBLE_H_
00002 #define _ENSEMBLE_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <vector>
00016 #include "coords.h"
00017 #include "perf.h"
00018
00019 #include "pfstream.h"
00020 #include "TimeWindow.h"
00021 #include "TimeSeries.h"
00022 #include "ThreeComponentSeismogram.h"
00023 #include "ComplexTimeSeries.h"
00024 #include "Hypocenter.h"
00025 #include "SeisppKeywords.h"
00026 namespace SEISPP {
00038 class TimeSeriesEnsemble : public Metadata
00039 {
00040 public:
00047 vector <TimeSeries> member;
00048
00052 TimeSeriesEnsemble();
00057 TimeSeriesEnsemble(int ntsin, int nsampin);
00094 TimeSeriesEnsemble(DatabaseHandle& dbhi,
00095 MetadataList& data_mdl,
00096 MetadataList& ensemble_mdl,
00097 AttributeMap& am);
00163 TimeSeriesEnsemble(DatabaseHandle& db,
00164 TimeWindow twin,
00165 const string sta_expression="none",
00166 const string chan_expression="none",
00167 bool require_coords=true,
00168 bool require_orientation=true,
00169 bool require_response=false);
00176 TimeSeriesEnsemble(Pf_ensemble *pfe);
00180 TimeSeriesEnsemble(const TimeSeriesEnsemble& tseold);
00189 TimeSeriesEnsemble(Metadata& md,int nmembers);
00193 TimeSeriesEnsemble& operator=(const TimeSeriesEnsemble& tseold);
00194 };
00195
00208 class ThreeComponentEnsemble : public Metadata
00209 {
00210 public:
00217 vector <ThreeComponentSeismogram> member;
00221 ThreeComponentEnsemble();
00226 ThreeComponentEnsemble(int nsta, int nsamp);
00232 ThreeComponentEnsemble(int nsta, int nsamp,
00233 MetadataList& mdl);
00254 ThreeComponentEnsemble(DatabaseHandle& db,
00255 MetadataList& station_mdl,
00256 MetadataList& ensemble_mdl,
00257 AttributeMap& am);
00283 ThreeComponentEnsemble(DatabaseHandle& dbhi,
00284 TimeWindow twin,
00285 MetadataList& ensemble_mdl,
00286 MetadataList& data_mdl,
00287 AttributeMap& am,
00288 vector<string>chanmap);
00292 ThreeComponentEnsemble(const ThreeComponentEnsemble& tseold);
00301 ThreeComponentEnsemble(Metadata& md,int nmembers);
00305 ThreeComponentEnsemble& operator=(const ThreeComponentEnsemble& tseold);
00306 };
00320 template <class Tmember>
00321 void remove_trace(Tmember& ensemble, int no)
00322 {
00323 if(no >= ensemble.member.size()) return;
00324 int i;
00325 typedef typename std::vector<Tmember> vector_type;
00326 typename vector_type::iterator it;
00327
00328 it=ensemble.member.begin();
00329 for(i=0;i<no;++i) ++it;
00330 ensemble.member.erase(it);
00331 }
00332
00333
00335 double PeakAmplitude(TimeSeries *p);
00338 double PeakAmplitude(ThreeComponentSeismogram *p);
00340 double PeakAmplitude(ComplexTimeSeries *p);
00341
00361 template <class Tensemble,class Tmember>
00362 void MeasureEnsemblePeakAmplitudes(Tensemble& d,
00363 string scale_attribute)
00364 {
00365 int i;
00366 double amplitude;
00367 for(i=0;i<d.member.size();++i)
00368 {
00369 Tmember *dp=&(d.member[i]);
00370 if(dp->live)
00371 {
00372 amplitude=PeakAmplitude(dp);
00373 dp->put(scale_attribute,amplitude);
00374 }
00375 }
00376 }
00377
00403 template <class Tensemble,class Tmember>
00404 void ScaleEnsemble(Tensemble& d,
00405 string scale_attribute,
00406 bool invert=false)
00407 {
00408 int i;
00409 double amplitude;
00410 for(i=0;i<d.member.size();++i)
00411 {
00412 Tmember *dp=&(d.member[i]);
00413 if(dp->live)
00414 {
00415 try {
00416 amplitude=dp->get_double(scale_attribute);
00417
00418 if(amplitude>0)
00419 {
00420 if(invert)
00421 ScaleMember(dp,1.0/amplitude);
00422 else
00423 ScaleMember(dp,amplitude);
00424 }
00425 }
00426 catch (MetadataGetError mde)
00427 {
00428 cerr << "Warning (ScaleEnsemble): "
00429 <<"scaling of data failed"<<endl;
00430 mde.log_error();
00431 cerr << "Continuing with data left unscaled"
00432 <<endl;
00433 }
00434 }
00435 }
00436 }
00437
00438
00440 void ScaleMember(TimeSeries *p,double scale);
00442 void ScaleMember(ThreeComponentSeismogram *p,double scale);
00444 void ScaleMember(ComplexTimeSeries *p,double scale);
00445
00446
00447
00471 template <class Tensemble> void ScaleCalib(Tensemble d,
00472 string calib_attribute,
00473 string scale_attribute,
00474 bool invert=false)
00475 {
00476 double calib;
00477 double scale;
00478 for(int i=0;i<d.member.size();++i)
00479 {
00480 if(d.member[i].live)
00481 {
00482 try {
00483 calib=d.member[i].get_double(calib_attribute);
00484 } catch (MetadataGetError mde)
00485 {
00486 calib=1.0;
00487 }
00488
00489 try {
00490 scale=d.member[i].get_double(scale_attribute);
00491 } catch (MetadataGetError mde)
00492 {
00493 scale=1.0;
00494 }
00495 if(invert) scale=1.0/scale;
00496 d.member[i].put(calib_attribute,scale*calib);
00497 }
00498 }
00499 }
00509 template <class Te, class Ta>
00510 void InitializeEnsembleAttribute(Te& d, string name,
00511 Ta val)
00512 {
00513 try {
00514 int i;
00515 for(i=0;i<d.member.size();++i)
00516 d.member[i].put(name,val);
00517 } catch(...){throw;};
00518 }
00556 template <class Tensemble> void LoadEventArrivals(Tensemble& d,
00557 DatabaseHandle& dbi,
00558 string phase,
00559 string predarrkeyword,
00560 string atkeyword,
00561 double tpad,
00562 double nullvalue)
00563 {
00564 DatascopeHandle dbh=dynamic_cast<DatascopeHandle&> (dbi);
00565 DatascopeHandle dbhss(dbh);
00566
00567
00568 TimeWindow atrange(-2.0,-1.0);
00569 double testval;
00570 bool firstpass(true);
00571 int i;
00572 for(i=0;i<d.member.size();++i)
00573 {
00574 if(d.member[i].is_attribute_set(predarrkeyword))
00575 {
00576 testval=d.member[i].get_double(predarrkeyword);
00577 if(firstpass)
00578 {
00579 atrange.start=testval;
00580 atrange.end=testval;
00581 firstpass=false;
00582 }
00583 else
00584 {
00585 if(atrange.start>testval)
00586 atrange.start=testval;
00587 if(atrange.end<testval)
00588 atrange.end=testval;
00589 }
00590 }
00591 }
00592 if(atrange.start<0.0)
00593 throw SeisppError(string("LoadEventArrivals: no predicted arrivals are defined")
00594 + string(" in ensemble passed to this procedure\n")
00595 + string("Coding error or problem in the way metadata were loaded.") );
00596 atrange.start -= tpad;
00597 atrange.end += tpad;
00598 char ssexpression[256];
00599 sprintf(ssexpression,"(time >= %lf && time<=%lf && iphase=~/%s/)",
00600 atrange.start,atrange.end,phase.c_str());
00601 dbhss.subset(string(ssexpression));
00602
00603
00604 for(i=0;i<d.member.size();++i)
00605 d.member[i].put(atkeyword,nullvalue);
00606 if(dbhss.number_tuples()>0)
00607 {
00608 try {
00609 map<string,double> atimes;
00610 map<string,double>::iterator atptr;
00611 double t;
00612 string sta;
00613 dbhss.rewind();
00614 for(i=0;i<dbhss.number_tuples();++i,++dbhss)
00615 {
00616 sta=dbhss.get_string("sta");
00617 t=dbhss.get_double("arrival.time");
00618 atimes[sta]=t;
00619 }
00620 for(i=0;i<d.member.size();++i)
00621 {
00622 sta=d.member[i].get_string("sta");
00623 atptr=atimes.find(sta);
00624 if(atptr!=atimes.end())
00625 {
00626 d.member[i].put(atkeyword,atptr->second);
00627 }
00628 }
00629 }
00630 catch (...)
00631 {
00632 throw SeisppError(string("LoadEventArrivals: ")
00633 + string("Problems arrivals. Not all arrivals were loaded") );
00634 }
00635 }
00636
00637
00638
00639
00640 }
00676 template <class Tensemble> int LoadPredictedArrivalTimes(Tensemble& d,
00677 string phase,
00678 string predarr_keyword=predicted_time_key,
00679 string ttmethod="tttaup",
00680 string ttmodel="iasp91",
00681 bool verbose=false)
00682 {
00683 int i,nmembers;
00684 double slat,slon,sz,stime;
00685 double rlat,rlon,relev;
00686 double phasetime;
00687 int nfailures(0);
00688
00689 nmembers=d.member.size();
00690 for(i=0;i<nmembers;++i)
00691 {
00692 if(d.member[i].live)
00693 {
00694 try{
00695 slat=d.member[i].get_double("source_lat");
00696 slon=d.member[i].get_double("source_lon");
00697 sz=d.member[i].get_double("source_depth");
00698 stime=d.member[i].get_double("source_time");
00699 rlat=d.member[i].get_double("sta_lat");
00700 rlon=d.member[i].get_double("sta_lon");
00701 relev=d.member[i].get_double("sta_elev");
00702 slat=rad(slat);
00703 slon=rad(slon);
00704 rlat=rad(rlat);
00705 rlon=rad(rlon);
00706 Hypocenter h(slat,slon,sz,stime,
00707 ttmethod,ttmodel);
00708 phasetime=h.phasetime(rlat,rlon,relev,phase);
00709 phasetime+=stime;
00710 }
00711 catch (MetadataGetError mderr)
00712 {
00713 phasetime=0.0;
00714 ++nfailures;
00715 if(verbose)
00716 {
00717 cerr << "LoadPredictedArrivalTimes: "
00718 << "get failed on attribute name="
00719 << mderr.name
00720 <<" for ensemble member number "
00721 << i <<endl
00722 << "Arrival time set to 0.0"<<endl;
00723 }
00724 }
00725 catch (SeisppError serr)
00726 {
00727 phasetime=0.0;
00728 ++nfailures;
00729 if(verbose)
00730 {
00731 cerr << "LoadPredictedArrivalTimes: "
00732 << "travel time calculator error "
00733 << "for member="<<i <<endl
00734 << "SeisppError message:"<<endl;
00735 serr.log_error();
00736 cerr << "Arrival time set to zero"<<endl;
00737 }
00738 }
00739
00740 }
00741 else
00742 {
00743 phasetime=0.0;
00744 }
00745 d.member[i].put(predarr_keyword,phasetime);
00746 }
00747 return(nfailures);
00748 }
00749
00765 auto_ptr<TimeSeriesEnsemble> ExtractComponent(ThreeComponentEnsemble& tcs,int component);
00766 }
00767 #endif