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; }
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; }
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; }