Seiscomp3系列--seiscomp3源码关于振幅和震级的测试代码

        Seiscomp3系统的代码量比较可观的,用代码统计工具算了一下,大概有49万行代码,主要以C/C++和python为主。如果没有C/C++基础的话,有不小的难度。最近因为工作的需要对Seiscop3的源码进行了部分走读,对系统的架构有一些了解,但对于代码细节还有待研究,此博客的目的主要是记录学习过程,希望给后来的同学一点启示,少走些弯路。当然了,因为本人的水平有限,记录的内容会有不少错误,也希望各位看官指出错误,并告知我。

        正是因为本系统的代码量庞大,研究Seiscomp3源码需要一个切入口,我选取的切入口,是源码中关于振幅和震级的测试例程。代码路径/seiscomp3-master/src/trunk/plugins/magnitudes/nuttli/test。主程序的入口在amplitudes.cpp中。

第一步,了解测试程序的结构。

此程序模块框图:

输入是包括三个文件:Charlevoix_MN2.4.mseed、Charlevoix_MN2.4.xml、inventory.xml。

这三个文件的路径在test所在的同级文件夹下面。

输出是Charlevoix_MN2.4_test.xml,xml文件里面包含振幅和震级。

第二步,源码分析

int main(int argc, char **argv) {
	TestApp test(argc, argv);
	return test();
}

程序入口,TestApp类继承自Client::Application类,在Application类中运算符重载了(),test()调用了父类的函数Application::operator()()-->Application::exec()-->run(),需要注意是此处的run重载了父类的Application::run(),程序运行时优先调用子类的run()函数。

以下代码有些难理解

			int i = 0;
			for ( AmplitudeMap::iterator it = originalAmplitudes.begin();
			      it != originalAmplitudes.end(); ++it, ++i ) {
				Pick *pick = Pick::Find(it->second.first->pickID());
				if ( pick == NULL ) {
					SEISCOMP_WARNING("Ignoring amplitude %d: pick not found",
					                 int(i));
					continue;
				}

				DataModel::SensorLocation *loc = DataModel::getSensorLocation(inv, pick);
				if ( loc == NULL ) {
					SEISCOMP_WARNING("Ignoring amplitude %d: %s.%s.%s: sensor location not found", int(i),
					                 pick->waveformID().networkCode().c_str(),
					                 pick->waveformID().stationCode().c_str(),
					                 pick->waveformID().locationCode().c_str());
					continue;
				}

				DataModel::Stream *chan = DataModel::getVerticalComponent(
					loc, pick->waveformID().channelCode().substr(0,2).c_str(),
					pick->time().value()
				);

				if ( chan == NULL ) {
					SEISCOMP_WARNING("Ignoring amplitude %d: vertical channel for %s.%s.%s not found",
					                 int(i),
					                 pick->waveformID().networkCode().c_str(),
					                 pick->waveformID().stationCode().c_str(),
					                 pick->waveformID().locationCode().c_str());
					continue;
				}

				string sid = pick->waveformID().networkCode() + "." +
				             pick->waveformID().stationCode() + "." +
				             loc->code() + "." + chan->code();

				if ( amplitudeProcStreamRoute.find(sid) != amplitudeProcStreamRoute.end() )
					// Same stream id already used
					continue;

				// Inject sid into existing

				Processing::Settings settings(configModuleName(),
				                              pick->waveformID().networkCode(),
				                              pick->waveformID().stationCode(),
				                              pick->waveformID().locationCode(),
				                              chan->code(),
				                              &configuration(), NULL);

				Processing::AmplitudeProcessorPtr proc;
				proc = Processing::AmplitudeProcessorFactory::Create(AMP_TYPE);

				proc->streamConfig(Processing::WaveformProcessor::VerticalComponent).init(chan);
				proc->setTrigger(pick->time().value());
				proc->setPick(pick);

				if ( !proc->setup(settings) ) {
					SEISCOMP_WARNING("Ignoring amplitude %d: processor for %s.%s.%s failed to setup: %s (%f)",
					                 int(i),
					                 pick->waveformID().networkCode().c_str(),
					                 pick->waveformID().stationCode().c_str(),
					                 pick->waveformID().locationCode().c_str(),
					                 proc->status().toString(),
					                 proc->statusValue());
					continue;
				}

				proc->setEnvironment(origin.get(), loc, pick);
				proc->computeTimeWindow();

				if ( proc->isFinished() ) {
					SEISCOMP_WARNING("Ignoring amplitude %d: processor %s.%s.%s has already finished: %s (%f)",
					                 int(i),
					                 pick->waveformID().networkCode().c_str(),
					                 pick->waveformID().stationCode().c_str(),
					                 pick->waveformID().locationCode().c_str(),
					                 proc->status().toString(),
					                 proc->statusValue());
					continue;
				}

				proc->setPublishFunction(boost::bind(&TestApp::publishAmplitude, this, _1, _2));
				amplitudeProcStreamRoute[sid] = proc;
				amplitudeProcPickRoute[it->second.first->pickID()] = proc;
				it->second.second = sid;

				file.addStream(pick->waveformID().networkCode(),
				               pick->waveformID().stationCode(),
				               loc->code(), chan->code(),
				               proc->safetyTimeWindow().startTime(),
				               proc->safetyTimeWindow().endTime());
			}

以上代码的大概意思是通过读取配置文件中的信息,去设置处理所需的参数,完成设置。要主要两个地方。

Processing::AmplitudeProcessorPtr proc;
                proc = Processing::AmplitudeProcessorFactory::Create(AMP_TYPE);这两行代码很具有迷惑性,利用C++的多态特性,父类指针指向子类对象,完成对子类功能函数的调用。

还有就是proc->setPublishFunction(boost::bind(&TestApp::publishAmplitude, this, _1, _2));此函数利用了boost的特性,如果对boost不熟的话,只需知道此处设置了回调函数即可。

 

如果各位看官有任何问题,可以在评论区给我留言,我会尽力协助解决,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值