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; }
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; }
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; }
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; }
//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; }
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; }
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; }
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 (μs)</th>" << "<th>sampling end (μ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μs" ) % start_delay << "</td>" << "<td>" << boost::format( "%.4lfμ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 << "√<span style=\"text-decoration: overline\"> <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 × 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 × √<span style=\"text-decoration: overline\"> <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(); } }