예제 #1
0
bool
rawdata::getSpectrum( int fcn, size_t pos, adcontrols::MassSpectrum& ms, uint32_t objid ) const
{
    auto it = std::find_if( conf_.begin(), conf_.end(), [=]( const adutils::AcquiredConf::data& c ){
            if ( objid == 0 )
                return c.trace_method == signalobserver::eTRACE_SPECTRA && c.trace_id == L"MS.PROFILE";
            else
                return c.objid == objid;
        });
    if ( it == conf_.end() )
        return false;

    adcontrols::translate_state state;
    uint64_t npos = npos0_ + pos;

    if ( fcn < 0 && fcnIdx_.size() > 1 ) {

        // find 'index' from <pos, fcn> array that indicates first 'pos' after protocol has been switched
        auto index = std::lower_bound( fcnIdx_.begin(), fcnIdx_.end(), npos
                                       , [] ( const std::pair< size_t, int >& a, size_t npos ) { return a.first < npos; } );
        if ( index == fcnIdx_.end() )
            return false;
        while ( index != fcnIdx_.begin() && index->first > npos )
            --index;
        int rep = int( npos - index->first );  // id within a replicates (rep'licates is the offset from (fcn=0,rep=0) spectrum)
        while ( index != fcnIdx_.begin() && index->second != 0 ) // find fcn=0
            --index;

        // read all protocols
        while ( ( state = fetchSpectrum( it->objid, it->dataInterpreterClsid, index->first + rep, ms, it->trace_id ) )
                == adcontrols::translate_indeterminate )
                if ( ++index == fcnIdx_.end() )  // move forward to next protocol (rep'licates is the offset for actual spectrum)
                    break;
    } else {

        state = fetchSpectrum( it->objid, it->dataInterpreterClsid, npos, ms, it->trace_id );

    }

    if ( ms.getMSProperty().dataInterpreterClsid() == 0 ) {
        // workaround for batchproc::import
        adcontrols::MSProperty prop = ms.getMSProperty();
        prop.setDataInterpreterClsid( adportable::utf::to_utf8( it->dataInterpreterClsid ).c_str() );
    }
    if ( fcn < 0 )
        return state == adcontrols::translate_complete;

    return state == adcontrols::translate_complete || state == adcontrols::translate_indeterminate;
}
예제 #2
0
bool
DataprocHandler::doMSCalibration( adcontrols::MSCalibrateResult& res
                                  , adcontrols::MassSpectrum& centroid
                                  , const adcontrols::MSCalibrateMethod& m
                                  , const adcontrols::MSAssignedMasses& assigned )
{
    using adcontrols::MSProperty;

    const double tolerance = m.massToleranceDa();
    const double threshold = centroid.getMaxIntensity() * m.minimumRAPercent() / 100;
    res.tolerance( tolerance );  // set tolerance in result
    res.threshold( threshold );  // set threshold in result

    std::map< size_t, size_t > mode_map;
    for ( adcontrols::MSAssignedMasses::vector_type::const_iterator it = assigned.begin(); it != assigned.end(); ++it ) 
        mode_map[ it->mode() ]++;
    // std::map<size_t, size_t>::iterator itMax = std::max_element( mode_map.begin(), mode_map.end() );
    // int mode = static_cast<int>(itMax->first);

    mass_calibrator calibrator( assigned, centroid.getMSProperty() );
    adcontrols::MSCalibration calib;
    if ( ! calibrator.polfit( calib, m.polynomialDegree() + 1 ) )
        return false;

    res.references( m.references() );
    res.calibration( calib );
    centroid.setCalibration( calib, true ); // m/z assign based on manually determined peaks

    // continue auto-assign
    assign_masses assign( tolerance, threshold );
    adcontrols::MSAssignedMasses assignedMasses;
	adcontrols::segment_wrapper< adcontrols::MassSpectrum > segments( centroid );
	for ( size_t n = 0; n < segments.size(); ++n ) {
		assign( assignedMasses, segments[n], m.references(), 0, static_cast<int>(n) );
	}

    mass_calibrator calibrator2( assignedMasses, centroid.getMSProperty() );
    if ( calibrator2.polfit( calib, m.polynomialDegree() + 1 ) ) {
        for ( auto it: assignedMasses )
            it.mass( calibrator2.compute_mass( it.time(), it.mode(), calib ) );

        centroid.setCalibration( calib, true );
        res.calibration( calib );
        res.assignedMasses( assignedMasses );

        return true;
    }
    return false;
}
예제 #3
0
bool
MappedSpectrum::transform( adcontrols::MassSpectrum& ms ) const
{
    auto& prop = ms.getMSProperty();

    int32_t nDelay = int32_t( ( delay_ / sampInterval_ ) + 0.5 );
    auto si = SamplingInfo( sampInterval_, delay_, nDelay, nSamples_, num_average_, 0 /* mode */ );
    si.fSampInterval( sampInterval_ );
    prop.setSamplingInfo( si );
    prop.setNumAverage( num_average_ );
    prop.setTrigNumber( trig_number_, trig_number_origin_ );
    prop.setTimeSinceEpoch( timeSinceEpoch_.second );

    ms.resize( data_.size() );
    ms.setCentroid( adcontrols::CentroidNative );
    //auto scanlaw = prop.scanLaw();
    
    for ( size_t idx = 0; idx < data_.size(); ++idx ) {
        double tof = this->time( idx );
        ms.setTime( idx, tof );
        //if ( scanlaw )
        //    ms.setMass( idx, ms.compute_mass( data_[ idx ].first ) ); 
        ms.setIntensity( idx, data_[ idx ].second );
    }
    return true;
}
예제 #4
0
bool
DataprocHandler::doMSCalibration( adcontrols::MSCalibrateResult& res
                                 , adcontrols::MassSpectrum& centroid
                                 , const adcontrols::MSCalibrateMethod& m )
{
    using adcontrols::MSProperty;

    res.calibration( centroid.calibration() );
    res.references( m.references() );
    double tolerance = m.massToleranceDa();
    double threshold = adcontrols::segments_helper::max_intensity( centroid ) * m.minimumRAPercent() / 100;
    res.tolerance( tolerance );
    res.threshold( threshold );

    assign_masses assigner( tolerance, threshold );

    adcontrols::MSAssignedMasses assignedMasses;
    
	adcontrols::segment_wrapper< adcontrols::MassSpectrum > segments( centroid );
    int n = 0;
	for ( auto seg: segments )
		assigner( assignedMasses, seg, res.references(), seg.mode(), n++ );

	res.assignedMasses( assignedMasses ); // set peak assign result

    // annotate each peak on spectrum
    doAnnotateAssignedPeaks( centroid, assignedMasses );

    mass_calibrator calibrator( assignedMasses, centroid.getMSProperty() );

    adcontrols::MSCalibration calib;
    if ( calibrator.polfit( calib, m.polynomialDegree() + 1 ) ) {
        for ( auto it: assignedMasses ) {
            double mass = calibrator.compute_mass( it.time(), it.mode(), calib );
            it.mass( mass );
        }
        res.calibration( calib );
        // res.assignedMasses( assignedMasses );
#if defined _DEBUG && 0
        calibresult_validation( res, centroid, threshold );
#endif
        return true;
    }
    return false;
}
예제 #5
0
//virtual
bool
datafile::getSpectrum( int fcn, size_t pos, adcontrols::MassSpectrum& ms, uint32_t objId ) const
{
	(void)fcn;

	try {
		EDAL::IMSSpectrumCollectionPtr pSpectra = pAnalysis_->GetMSSpectrumCollection();
		EDAL::IMSSpectrumPtr pSpectrum = pSpectra->GetItem( long(pos) + 1 ); // 1-origin

		if ( pSpectrum->Polarity == EDAL::SpectrumPolarity::IonPolarity_Negative )
			ms.setPolarity( adcontrols::MS_POLARITY::PolarityNegative );
		else if ( pSpectrum->Polarity == EDAL::SpectrumPolarity::IonPolarity_Positive )
			ms.setPolarity( adcontrols::MS_POLARITY::PolarityPositive );
		else
			ms.setPolarity( adcontrols::MS_POLARITY::PolarityIndeterminate );

		adcontrols::MSProperty prop = ms.getMSProperty();
		prop.setTimeSinceInjection( static_cast< unsigned long >( pSpectrum->RetentionTime /* sec */ * 1.0e6 ) ); // usec
        ms.setMSProperty( prop ); // <- end of prop set

		_variant_t vMasses, vIntens;
        if ( objId <= 1 ) {
			pSpectrum->GetMassIntensityValues( EDAL::SpectrumType_Profile, &vMasses, &vIntens );
			ms.setCentroid( adcontrols::CentroidNone );  // profile
        } else { // objId should be 2
			pSpectrum->GetMassIntensityValues( EDAL::SpectrumType_Line, &vMasses, &vIntens );
			ms.setCentroid( adcontrols::CentroidNative );
		}

		SafeArray sa_masses( vMasses );
        ms.resize( sa_masses.size() );
        ms.setMassArray( reinterpret_cast< const double *>( sa_masses.p() ) );
    
		SafeArray sa_intensities( vIntens );
        ms.setIntensityArray( reinterpret_cast< const double *>( sa_intensities.p() ) );

        ms.setAcquisitionMassRange( ms.getMass( 0 ), ms.getMass( ms.size() - 1 ) );

		return true;
	} catch(_com_error& ex ) {
		ADERROR() << std::wstring( ex.ErrorMessage() );
		return false;
	}
	return false;
}
예제 #6
0
bool
TimeDigitalHistogram::translate( adcontrols::MassSpectrum& sp
                                 , const TimeDigitalHistogram& hgrm
                                 , mass_assignor_t mass_assignee )
{
    if ( translate( sp, hgrm ) ) {
        const adcontrols::MSProperty& prop = sp.getMSProperty();
        const auto& sinfo = prop.samplingInfo();
        
        double lMass = mass_assignee( sinfo.fSampDelay(), prop.mode() );
        double hMass = mass_assignee( sinfo.fSampDelay() + sinfo.fSampInterval() * sinfo.nSamples(), prop.mode() );
        
        sp.setAcquisitionMassRange( lMass, hMass );

        return sp.assign_masses( mass_assignee );
    }
    return false;
}
예제 #7
0
bool
waveform::fft::lowpass_filter( adcontrols::MassSpectrum& ms, double freq )
{
    if ( ms.isCentroid() )
        return false;

    size_t totalSize = ms.size();
	(void)totalSize;
	size_t N = 32;
    while ( N < ms.size() )
		N *= 2;
	const size_t NN = ms.size();
	double sampInterval = ms.getMSProperty().getSamplingInfo().fSampInterval(); // seconds
    if ( sampInterval == 0 )
        sampInterval = ( ms.getTime( ms.size() - 1 ) - ms.getTime( 0 ) ) / ms.size();
    const double T = N * sampInterval;  // time full scale in seconds.  Freq = n/T (Hz)
    // power spectrum has N/2 points and is n/T Hz horizontal axis  := data[N/2] = (N/2)/T Hz
    size_t cutoff = size_t( T * freq );

	adportable::array_wrapper<const double> pIntens( ms.getIntensityArray(), N );

	std::vector< std::complex<double> > spc( N );
	std::vector< std::complex<double> > fft( N );
	size_t n;
	for ( n = 0; n < N && n < NN; ++n )
		spc[ n ] = std::complex<double>( pIntens[ n ] );
	while ( n < N )
		spc[ n++ ] = pIntens[ NN - 1 ];

	adportable::fft::fourier_transform( fft, spc, false );
    // appodization
    for ( size_t i = cutoff; i < N - cutoff; ++i )
        fft[ i ] = 0;
    //adportable::fft::apodization( N/2 - N/16, N / 16, fft );
	adportable::fft::fourier_transform( spc, fft, true );

	std::vector<double> data( N );
	for ( size_t i = 0; i < NN; ++i )
		data[ i ] = spc[i].real();

	ms.setIntensityArray( &data[0] );

	return true;
}
예제 #8
0
void
MSPropertyForm::render( std::ostream& o, const adcontrols::MassSpectrum& ms )
{
    using adportable::utf;
    using namespace adcontrols::metric;

    static const char * const polarities [] = { "Indeterminant", "Positive", "Negative", "Mixed" };

    adcontrols::segment_wrapper< const adcontrols::MassSpectrum > segments( ms );

    std::vector< std::pair< std::string, std::string > > temp;
    temp.push_back( std::make_pair( "Spectrum", ( ms.isCentroid() ? "Centroid" : "Profile" ) ) );
    temp.push_back( std::make_pair( "Polarity", polarities[ ms.polarity() ] ) );

    o << "<hr>";
    o << "<table border=\"1\" cellpadding=\"1\">";
    o << "<caption>Descriptions</caption>";
    o << "<tr>";
    o << "<th>key</th>"
      << "<th>description</th>"
      << "</tr>";
    for ( auto it: temp ) {
        o << "<tr>"
          << "<td>" << it.first << "</td>"
          << "<td>" << it.second << "</td>"
          << "</tr>";
    }
    for ( size_t i = 0; i < ms.getDescriptions().size(); ++i ) {
        auto desc = ms.getDescriptions()[ i ];
        o << "<tr>"
          << "<td>" << utf::to_utf8( desc.key() ) << "</td>"
          << "<td>" << utf::to_utf8( desc.text() ) << "</td>"
          << "</tr>";
    }
    o << "</table>";

    std::pair< double, double > massrange = ms.getAcquisitionMassRange();
    o << "Acquisition mass range: " << boost::format( "%.3lf -- %.3lf" ) % massrange.first % massrange.second;

    o << "<table border=\"1\" cellpadding=\"4\">";
    o << "<caption>Acquisition and calibration parameter(s)</caption>";
    o << "<tr>";
    o << "<th>#seg</th>"
      << "<th>samp. interval(ps)</th>"
      << "<th>sampling start (&mu;s)</th>"
      << "<th>sampling end (&mu;s)</th>"
      << "<th>num. samples</th>"
      << "<th>num. average</th>"
      << "<th>mode</th>"
      << "<th>classid</th>"
      << "</tr>";
    int n = 0;
    for ( auto& m: segments ) {
        const adcontrols::MSCalibration& calib =  m.calibration();
        size_t nrowspan = calib.coeffs().empty() ? 1 : 2;
        const adcontrols::MSProperty& prop = m.getMSProperty();
        const adcontrols::MSProperty::SamplingInfo& info = prop.getSamplingInfo();
        double start_delay = scale_to<double, micro>( info.sampInterval * info.nSamplingDelay, pico );
        double time_end = scale_to<double, micro>( info.sampInterval * ( info.nSamplingDelay + info.nSamples ), pico );
        o << "<tr>"
          << boost::format( "<td rowspan=\"%1%\">" ) % nrowspan << n++ << "</td>"
          << "<td>" << info.sampInterval << "</td>"
          << "<td>" << boost::format( "%.4lf&mu;s" ) % start_delay << "</td>"
          << "<td>" << boost::format( "%.4lf&mu;s" ) % time_end << "</td>"
          << "<td>" << info.nSamples << "</td>"
          << "<td>" << info.nAverage << "</td>"
          << "<td>" << info.mode << "</td>"
		  << "<td>" << prop.dataInterpreterClsid() << "</td>"
          << "</tr>";

        if ( ! calib.coeffs().empty() ) {
            //-----------------------------
            o << "<tr>";
            o << "<td colspan=7><b>Calibration ID:</b><i>" << utf::to_utf8( calib.calibId() ) << "</i>"
              << "     " << calib.date();
            o << "<hr>";
            o << "&radic;<span style=\"text-decoration: overline\">&nbsp;<i>m/z</i></span> = "
              << boost::format( "%.14lf" ) % calib.coeffs()[0] << " + ";
            for ( size_t i = 1; i < calib.coeffs().size(); ++i )
                o << boost::format( "\t%.14lf &times; t<sup>%d</sup>" ) % calib.coeffs()[i] % i;

            if ( ! calib.t0_coeffs().empty() ) {
                o << "<br>"
                  << "T<sub>0</sub> = " << calib.t0_coeffs()[0];
                for ( size_t i = 1; i < calib.t0_coeffs().size(); ++i )
                    o << boost::format( "\t%.14lf &times; &radic;<span style=\"text-decoration: overline\">&nbsp;<i>m/z</i></span><sup>%d</sup>" )
                        % calib.coeffs()[i] % i;
                if ( calib.algorithm() == adcontrols::MSCalibration::MULTITURN_NORMALIZED )
                    o << "\t(MULTITURN_NORMAILZED algorithm)";
            }
            o << "</tr>";
            //-----------------------------            
		}
    }
    o << "</table>";
    o << "<hr>";

    try {
        // device (averager) dependent data (require data interpreter)
        std::vector < std::pair< std::string, std::string > > textv;
        auto& prop = ms.getMSProperty();
        const char * ipClsid = prop.dataInterpreterClsid();
        if ( ipClsid && (std::strlen( ipClsid )) > 0 ) {
            auto& interpreter = prop.spectrometer().getDataInterpreter();
            if ( interpreter.make_device_text( textv, ms.getMSProperty() ) ) {
                o << "<table border=\"1\" cellpadding=\"4\">";
                o << "<caption>Averager/digitizer dependent information</caption>";
                o << "<tr>";
                o << "<th>#seg</th>";
                std::for_each( textv.begin(), textv.end(), [&] ( const std::pair< std::string, std::string>& text ) { o << "<th>" << text.first << "</th>"; } );
                o << "</tr>";
                int seg = 0;
                for ( auto& m : segments ) {
                    if ( interpreter.make_device_text( textv, m.getMSProperty() ) ) {
                        o << "<tr>";
                        o << "<td>" << seg++ << "</td>";
                        std::for_each( textv.begin(), textv.end(), [&] ( const std::pair< std::string, std::string>& text ) { o << "<td>" << text.second << "</td>"; } );
                        o << "</tr>";
                    }
                }
                o << "</table>";
                o << "<hr>";
            }
        }
        else {
            o << "<hr>No dataInterpreterClsid specifid.</hr>";
            ADERROR() << "no dataInterpreterClisidSpecified.";
        }
    }
    catch ( boost::exception& ex ) {
        o << "<hr>data exception: " << boost::diagnostic_information( ex ) << "</hr>";
        ADERROR() << boost::diagnostic_information( ex );
    }
    catch ( ... ) {
        o << "<hr>data exception: " << boost::current_exception_diagnostic_information() << "</hr>";
        ADERROR() << boost::current_exception_diagnostic_information();
    }
}