void waveform_generator::onTriggered() { std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now(); timeStamp_ = std::chrono::duration< uint64_t, std::pico >( now - __uptime__ ).count(); // ps noise __noise__( -15.0, 35.0 ); using namespace adcontrols::metric; double seconds = scale_to_base<double>( double(timeStamp_), pico ); double hf = ( std::sin( seconds / 10.0 ) + 1.20 ) / 2.20; std::vector< double > times; static int counter; std::ostringstream o; auto d = std::chrono::duration< uint64_t, std::nano >( now - __last__ ).count(); o << "onTriggerd: " << counter++ << " t: " << seconds << " " << int( d / 1000000); // ms __last__ = now; for ( const auto& ion: ions_ ) { double t = scanLaw.getTime( ion.mass, int(0) ); times.push_back( t ); o << "\tm/z=" << std::setprecision(4) << std::fixed << ion.mass << " tof=" << scale_to_micro(t); } ADINFO() << o.str(); size_t idx = 0; for ( int32_t& d: waveform_ ) { double t = scale_to_base<double>( ( nStartDelay_ + idx++ ) * double(sampInterval_), pico ); auto itIon = ions_.begin(); auto itTime = times.begin(); double y = 0; while ( itIon != ions_.end() && itTime != times.end() ) { boost::math::normal_distribution< double > nd( *itTime /* mean */, itIon->width /* sd */); // 10ns width y += boost::math::pdf( nd, t ) / boost::math::pdf( nd, *itTime ) * itIon->height * hf + __noise__(); ++itIon; ++itTime; } d = int32_t(y) + 10000; // add background (simulate high background level) } }
double fLength( int mode ) const override { return t_.fLength( mode ); }
double getTime( double mass, double fLength ) const override { return t_.getTime( mass, fLength ); }
double getMass( double secs, double fLength ) const override { return t_.getMass( secs, fLength ); }
double getTime( double mass, int mode ) const override { return t_.getTime( mass, mode ); }
double getMass( double secs, int mode ) const override { return t_.getMass( secs, mode ); }
double waveform_generator::mass_to_time( double mass, int nTurn ) { return scanLaw.getTime( mass, nTurn ); }