Beispiel #1
0
int
main(int argc, char **argv)
{
	pthread_t signal_thread;
	static thread_data tdata;
	int result;
	int option_index;
	struct option long_options[] = {
		{ "bell",	   0, NULL, 'b'},
		{ "help",	   0, NULL, 'h'},
		{ "version",   0, NULL, 'v'},
		{ "list",	   0, NULL, 'l'},
		{ "driver",    1, NULL, 'd'},
		{0, 0, NULL, 0} /* terminate */
	};

	tdata.hModule = NULL;
	tdata.dwSpace = 0;
	tdata.table = NULL;
	char *driver = NULL;
	boolean use_bell = FALSE;

	while((result = getopt_long(argc, argv, "bhvln:d:",
								long_options, &option_index)) != -1) {
		switch(result) {
		case 'b':
			use_bell = TRUE;
			break;
		case 'h':
			fprintf(stderr, "\n");
			show_usage(argv[0]);
			fprintf(stderr, "\n");
			show_options();
			fprintf(stderr, "\n");
			show_channels();
			fprintf(stderr, "\n");
			exit(0);
			break;
		case 'v':
			fprintf(stderr, "%s %s\n", argv[0], version);
			fprintf(stderr, "signal check utility for BonDriver based tuners.\n");
			exit(0);
			break;
		case 'l':
			show_channels();
			exit(0);
			break;
		case 'd':
			driver = optarg;
			break;
		}
	}

	if(argc - optind < 1) {
		fprintf(stderr, "channel must be specified!\n");
		fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
		return 1;
	}

	/* set tune_persistent flag */
	tdata.tune_persistent = TRUE;

	/* spawn signal handler thread */
	init_signal_handlers(&signal_thread, &tdata);

	/* tune */
	if(tune(argv[optind], &tdata, driver) != 0)
		return 1;

	while(1) {
		if(f_exit)
			break;
		tdata.pIBon->PurgeTsStream();	// 凡ドラはCh設定時からストリームデータをバッファに溜め込むため追加
		/* show signal strength */
		calc_cn(&tdata, use_bell);
		sleep(1);
	}

	/* wait for signal thread */
	pthread_kill(signal_thread, SIGUSR1);
	pthread_join(signal_thread, NULL);

	/* close tuner */
	if(close_tuner(&tdata) != 0)
		return 1;

	return 0;
}
Beispiel #2
0
int
tune(char *channel, thread_data *tdata, char *driver)
{
	/* get channel */
	BON_CHANNEL_SET *channel_set = searchrecoff(tdata->dwSpace, channel);
	if(channel_set == NULL) {
		fprintf(stderr, "Invalid Channel: %s\n", channel);
		return 1;
	}
	DWORD dwSendBonNum;
	boolean reqChannel;
	fprintf(stderr, "Space = %d\n", channel_set->bon_space);
	if(channel_set->bon_num != ARIB_CH_ERROR){
		dwSendBonNum = channel_set->bon_num;
		reqChannel = FALSE;
		fprintf(stderr, "Channel = B%d\n", channel_set->bon_num);
	}else{
		dwSendBonNum = channel_set->set_freq;
		reqChannel = TRUE;
		fprintf(stderr, "Channel = %dkHz\n", channel_set->set_freq);
	}

	/* open tuner */
	char *dri_tmp = driver;
	int aera;
	char **tuner;
	int num_devs;
	if(dri_tmp && *dri_tmp == 'P'){
		// proxy
		dri_tmp++;
		aera = 1;
	}else
		aera = 0;
	if(dri_tmp && *dri_tmp != '\0') {
		/* case 1: specified tuner driver */
		int num = 0;
		int code;

		if(*dri_tmp == 'S'){
			if(channel_set->type != CHTYPE_GROUND){
				if(aera == 0){
					tuner = bsdev;
					num_devs = NUM_BSDEV;
				}else{
					tuner = bsdev_proxy;
					num_devs = NUM_BSDEV_PROXY;
				}
			}else
				goto OPEN_TUNER;
		}else if(*dri_tmp == 'T'){
			if(channel_set->type != CHTYPE_SATELLITE){
				if(aera == 0){
					tuner = isdb_t_dev;
					num_devs = NUM_ISDB_T_DEV;
				}else{
					tuner = isdb_t_dev_proxy;
					num_devs = NUM_ISDB_T_DEV_PROXY;
				}
			}else
				goto OPEN_TUNER;
		}else
			goto OPEN_TUNER;
		if(!isdigit(*++dri_tmp))
			goto OPEN_TUNER;
		do{
			num = num * 10 + *dri_tmp++ - '0';
		}while(isdigit(*dri_tmp));
		if(*dri_tmp == '\0' && num+1 <= num_devs)
			driver = tuner[num];
OPEN_TUNER:;
		if((code = open_tuner(tdata, driver))){
			if(code == -4)
				fprintf(stderr, "OpenTuner error: %s\n", driver);
			return 1;
		}
		/* tune to specified channel */
		while(tdata->pIBon2->SetChannel(channel_set->bon_space, dwSendBonNum) == FALSE) {
			if(tdata->tune_persistent) {
				if(f_exit)
					goto err;
				fprintf(stderr, "No signal. Still trying: %s\n", driver);
			}
			else {
				fprintf(stderr, "Cannot tune to the specified channel: %s\n", driver);
				goto err;
			}
		}
		fprintf(stderr, "driver = %s\n", driver);
	}
	else {
		/* case 2: loop around available devices */
		int lp;

		switch(channel_set->type){
			case CHTYPE_BonNUMBER:
			default:
				fprintf(stderr, "No driver name\n");
				goto err;
			case CHTYPE_SATELLITE:
				if(aera == 0){
					tuner = bsdev;
					num_devs = NUM_BSDEV;
				}else{
					tuner = bsdev_proxy;
					num_devs = NUM_BSDEV_PROXY;
				}
				break;
			case CHTYPE_GROUND:
				if(aera == 0){
					tuner = isdb_t_dev;
					num_devs = NUM_ISDB_T_DEV;
				}else{
					tuner = isdb_t_dev_proxy;
					num_devs = NUM_ISDB_T_DEV_PROXY;
				}
				break;
		}

		for(lp = 0; lp < num_devs; lp++) {
			if(open_tuner(tdata, tuner[lp]) == 0) {
				// 同CHチェック
				DWORD m_dwSpace = tdata->pIBon2->GetCurSpace();
				DWORD m_dwChannel = tdata->pIBon2->GetCurChannel();
				if(m_dwSpace == channel_set->bon_space && m_dwChannel == dwSendBonNum)
					goto SUCCESS_EXIT;
				else{
					close_tuner(tdata);
					continue;
				}
			}
		}
		for(lp = 0; lp < num_devs; lp++) {
			int count = 0;

			if(open_tuner(tdata, tuner[lp]) == 0) {
				// 使用中チェック・BSのCh比較は、局再編があると正しくない可能性がある
				DWORD m_dwSpace = tdata->pIBon2->GetCurSpace();
				DWORD m_dwChannel = tdata->pIBon2->GetCurChannel();
				if(m_dwChannel != ARIB_CH_ERROR){
					if(m_dwSpace != channel_set->bon_space || m_dwChannel != dwSendBonNum){
						close_tuner(tdata);
						continue;
					}
				}else{
					/* tune to specified channel */
					if(tdata->tune_persistent) {
						while(tdata->pIBon2->SetChannel(channel_set->bon_space, dwSendBonNum) == FALSE && count < MAX_RETRY) {
							if(f_exit)
								goto err;
							fprintf(stderr, "No signal. Still trying: %s\n", tuner[lp]);
							count++;
						}

						if(count >= MAX_RETRY) {
							close_tuner(tdata);
							count = 0;
							continue;
						}
					} /* tune_persistent */
					else {
						if(tdata->pIBon2->SetChannel(channel_set->bon_space, dwSendBonNum) == FALSE) {
							close_tuner(tdata);
							continue;
						}
					}
				}

				goto SUCCESS_EXIT; /* found suitable tuner */
			}
		}

		/* all tuners cannot be used */
		fprintf(stderr, "Cannot tune to the specified channel\n");
		return 1;

SUCCESS_EXIT:
		if(tdata->tune_persistent)
			fprintf(stderr, "driver = %s\n", tuner[lp]);
	}
	tdata->table = channel_set;
	if(reqChannel) {
		channel_set->bon_space = tdata->pIBon2->GetCurSpace();
		channel_set->bon_num = tdata->pIBon2->GetCurChannel();
	}
	// TS受信開始待ち
	timespec ts;
	ts.tv_sec = 0;
	ts.tv_nsec = 50 * 1000 * 1000;	// 50ms
	{
	int lop = 0;
	do{
		nanosleep(&ts, NULL);
	}while(tdata->pIBon->GetReadyCount() < 2 && ++lop < 20);
	}

	if(!tdata->tune_persistent) {
		/* show signal strength */
		calc_cn(tdata, FALSE);
	}

	return 0; /* success */
err:
	close_tuner(tdata);

	return 1;
}
Beispiel #3
0
bool TASReso::SetHKLE(t_real h, t_real k, t_real l, t_real E)
{
	static const t_real s_dPlaneDistTolerance = std::cbrt(tl::get_epsilon<t_real>());

	ResoResults& resores = m_res[0];

	//std::cout << "UB = " << m_opts.matUB << std::endl;
	//std::cout << h << " " << k << " " << l << ", " << E << std::endl;
	if(m_opts.matUB.size1() < 3 || m_opts.matUB.size2() < 3)
	{
		const char* pcErr = "Invalid UB matrix.";
		tl::log_err(pcErr);
		resores.strErr = pcErr;
		resores.bOk = false;
		return false;
	}

	t_vec vecHKLE;
	if(m_opts.matUB.size1() == 3)
		vecHKLE = tl::make_vec({h, k, l});
	else
		vecHKLE = tl::make_vec({h, k, l, E});

	t_vec vecQ = ublas::prod(m_opts.matUB, vecHKLE);
	if(vecQ.size() > 3)
		vecQ.resize(3, true);

	m_tofreso.Q = m_reso.Q = ublas::norm_2(vecQ) / angs;
	m_tofreso.E = m_reso.E = E * meV;

	//tl::log_info("kfix = ", m_dKFix, ", E = ", E, ", Q = ", vecQ);
	wavenumber kother = tl::get_other_k(m_reso.E, m_dKFix/angs, m_bKiFix);
	//tl::log_info("kother = ", t_real(kother*angs));
	if(m_bKiFix)
	{
		m_tofreso.ki = m_reso.ki = m_dKFix / angs;
		m_tofreso.kf = m_reso.kf = kother;
	}
	else
	{
		m_tofreso.ki = m_reso.ki = kother;
		m_tofreso.kf = m_reso.kf = m_dKFix / angs;
	}

	m_reso.thetam = units::abs(tl::get_mono_twotheta(m_reso.ki, m_reso.mono_d, /*m_reso.dmono_sense>=0.*/1)*t_real(0.5));
	m_reso.thetaa = units::abs(tl::get_mono_twotheta(m_reso.kf, m_reso.ana_d, /*m_reso.dana_sense>=0.*/1)*t_real(0.5));
	m_tofreso.twotheta = m_reso.twotheta = units::abs(tl::get_sample_twotheta(m_reso.ki, m_reso.kf, m_reso.Q, 1));

	//tl::log_info("thetam = ", tl::r2d(m_reso.thetam/rads));
	//tl::log_info("thetaa = ", tl::r2d(m_reso.thetaa/rads));
	//tl::log_info("twothetas = ", tl::r2d(m_reso.twotheta/rads));

	m_tofreso.angle_ki_Q = m_reso.angle_ki_Q = tl::get_angle_ki_Q(m_reso.ki, m_reso.kf, m_reso.Q, /*m_reso.dsample_sense>=0.*/1);
	m_tofreso.angle_kf_Q = m_reso.angle_kf_Q = tl::get_angle_kf_Q(m_reso.ki, m_reso.kf, m_reso.Q, /*m_reso.dsample_sense>=0.*/1);

	//tl::log_info("kiQ = ", tl::r2d(m_reso.angle_ki_Q/rads));
	//m_reso.angle_ki_Q = units::abs(m_reso.angle_ki_Q);
	//m_reso.angle_kf_Q = units::abs(m_reso.angle_kf_Q);


	if(m_foc != ResoFocus::FOC_UNCHANGED)
	{
		if((unsigned(m_foc) & unsigned(ResoFocus::FOC_MONO_FLAT)) != 0)		// flat mono
			m_reso.bMonoIsCurvedH = m_reso.bMonoIsCurvedV = 0;
		if((unsigned(m_foc) & unsigned(ResoFocus::FOC_MONO_H)) != 0)		// optimally curved mono (h)
			m_reso.bMonoIsCurvedH = m_reso.bMonoIsOptimallyCurvedH = 1;
		if((unsigned(m_foc) & unsigned(ResoFocus::FOC_MONO_V)) != 0)		// optimally curved mono (v)
			m_reso.bMonoIsCurvedV = m_reso.bMonoIsOptimallyCurvedV = 1;

		if((unsigned(m_foc) & unsigned(ResoFocus::FOC_ANA_FLAT)) != 0)		// flat ana
			m_reso.bAnaIsCurvedH = m_reso.bAnaIsCurvedV = 0;
		if((unsigned(m_foc) & unsigned(ResoFocus::FOC_ANA_H)) != 0)			// optimally curved ana (h)
			m_reso.bAnaIsCurvedH = m_reso.bAnaIsOptimallyCurvedH = 1;
		if((unsigned(m_foc) & unsigned(ResoFocus::FOC_ANA_V)) != 0)			// optimally curved ana (v)
			m_reso.bAnaIsCurvedV = m_reso.bAnaIsOptimallyCurvedV = 1;

		//tl::log_info("Mono focus (h,v): ", m_reso.bMonoIsOptimallyCurvedH, ", ", m_reso.bMonoIsOptimallyCurvedV);
		//tl::log_info("Ana focus (h,v): ", m_reso.bAnaIsOptimallyCurvedH, ", ", m_reso.bAnaIsOptimallyCurvedV);

		// remove collimators
		/*if(m_reso.bMonoIsCurvedH)
		{
			m_reso.coll_h_pre_mono = 99999. * rads;
			m_reso.coll_h_pre_sample = 99999. * rads;
		}
		if(m_reso.bMonoIsCurvedV)
		{
			m_reso.coll_v_pre_mono = 99999. * rads;
			m_reso.coll_v_pre_sample = 99999. * rads;
		}
		if(m_reso.bAnaIsCurvedH)
		{
			m_reso.coll_h_post_sample = 99999. * rads;
			m_reso.coll_h_post_ana = 99999. * rads;
		}
		if(m_reso.bAnaIsCurvedV)
		{
			m_reso.coll_v_post_sample = 99999. * rads;
			m_reso.coll_v_post_ana = 99999. * rads;
		}*/
	}


	/*tl::log_info("thetam = ", m_reso.thetam);
	tl::log_info("thetaa = ", m_reso.thetaa);
	tl::log_info("2theta = ", m_reso.twotheta);*/

	if(std::fabs(vecQ[2]) > s_dPlaneDistTolerance)
	{
		tl::log_err("Position Q = (", h, " ", k, " ", l, "),",
			" E = ", E, " meV not in scattering plane.");

		resores.strErr = "Not in scattering plane.";
		resores.bOk = false;
		return false;
	}

	vecQ.resize(2, true);
	m_opts.dAngleQVec0 = -tl::vec_angle(vecQ);
	//tl::log_info("angle Q vec0 = ", m_opts.dAngleQVec0);
	//tl::log_info("calc r0: ", m_reso.bCalcR0);

	for(ResoResults& resores_cur : m_res)
	{
		// if only one sample position is requested, don't randomise
		if(m_res.size() > 1)
		{
			/*m_reso.pos_x = tl::rand_real(-t_real(m_reso.sample_w_q*0.5/cm),
				t_real(m_reso.sample_w_q*0.5/cm)) * cm;
			m_reso.pos_y = tl::rand_real(-t_real(m_reso.sample_w_perpq*0.5/cm),
				t_real(m_reso.sample_w_perpq*0.5/cm)) * cm;
			m_reso.pos_z = tl::rand_real(-t_real(m_reso.sample_h*0.5/cm),
				t_real(m_reso.sample_h*0.5/cm)) * cm;*/

			m_reso.pos_x = tl::rand_norm(t_real(0),
				t_real(tl::get_FWHM2SIGMA<t_real>()*m_reso.sample_w_q/cm)) * cm;
			m_reso.pos_y = tl::rand_norm(t_real(0),
				t_real(tl::get_FWHM2SIGMA<t_real>()*m_reso.sample_w_perpq/cm)) * cm;
			m_reso.pos_z = tl::rand_norm(t_real(0),
				t_real(tl::get_FWHM2SIGMA<t_real>()*m_reso.sample_h/cm)) * cm;
		}

		// calculate resolution at (hkl) and E
		if(m_algo == ResoAlgo::CN)
		{
			//tl::log_info("Algorithm: Cooper-Nathans (TAS)");
			resores_cur = calc_cn(m_reso);
		}
		else if(m_algo == ResoAlgo::POP)
		{
			//tl::log_info("Algorithm: Popovici (TAS)");
			resores_cur = calc_pop(m_reso);
		}
		else if(m_algo == ResoAlgo::ECK)
		{
			//tl::log_info("Algorithm: Eckold-Sobolev (TAS)");
			resores_cur = calc_eck(m_reso);
		}
		else if(m_algo == ResoAlgo::VIOL)
		{
			//tl::log_info("Algorithm: Violini (TOF)");
			m_reso.flags &= ~CALC_R0;
			resores_cur = calc_viol(m_tofreso);
		}
		else
		{
			const char* pcErr = "Unknown algorithm selected.";
			tl::log_err(pcErr);
			resores_cur.strErr = pcErr;
			resores_cur.bOk = false;
			return false;
		}

		if(!resores_cur.bOk)
		{
			tl::log_err("Error calculating resolution: ", resores_cur.strErr);
			tl::log_debug("R0: ", resores_cur.dR0);
			tl::log_debug("res: ", resores_cur.reso);
		}
	}

	return resores.bOk;
}