00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef OPENMS_FORMAT_HANDLERS_ANDIHANDLER_H
00028 #define OPENMS_FORMAT_HANDLERS_ANDIHANDLER_H
00029
00030 #include <netcdf.h>
00031 #include <ms10.h>
00032 #include <fstream>
00033 #include <sstream>
00034
00035 #include <OpenMS/CONCEPT/Exception.h>
00036 #include <OpenMS/KERNEL/MSExperiment.h>
00037 #include <OpenMS/CONCEPT/ProgressLogger.h>
00038
00039 namespace OpenMS
00040 {
00041 namespace Internal
00042 {
00050 template <typename MapType>
00051 class ANDIHandler
00052 {
00053 public:
00056
00057 ANDIHandler(MapType& exp, const ProgressLogger& logger)
00058 : exp_(exp),
00059 pol_(),
00060 logger_(logger)
00061 {
00062 MetaInfoRegistry& registry = MetaInfo().registry();
00063 for (int i=0; i<NUM_PARAM; i++)
00064 {
00065 registry.registerName(user_params_[i], description_[i]);
00066 }
00067 }
00069 virtual ~ANDIHandler()
00070 {
00071 }
00073
00075 void parse(std::string file_name);
00076
00077 protected:
00080
00081 void getAdminData_(MS_Admin_Data* admin_data);
00082
00084 void getSampleData_(MS_Sample_Data* sample_data);
00085
00087 void getTestData_(MS_Test_Data* test_data);
00088
00090 void getInstrumentData_(MS_Instrument_Data* inst_data);
00091
00093 void getRawPerScan_(MS_Raw_Per_Scan* scan_data, MS_Raw_Data_Global* global_data);
00095
00097 MapType& exp_;
00099 IonSource::Polarity pol_;
00100
00103
00104 enum userParamsID {CONTACT=0, PROC, ANDI_ERROR, CALHIST, CALTIMES,
00105 INSTSERIAL, INSTCOMMENTS, INSTSOFTWARE, INSTFIRMWARE,
00106 INSTOS, INSTID, INLETTEMP, IONMODEADD, SRCTEMP, ACCPOT,
00107 INSTPARAMS, DETPOT, DETENTRPOT, NUM_PARAM};
00109 static const std::string user_params_[];
00111 static const std::string description_[];
00113
00115 inline String string_(char* input)
00116 {
00117 return (input == NULL)? "" : String(input);
00118 }
00119
00125 inline float float_(float input, float def=0.0f)
00126 {
00127 return (input < -1000)? def : input;
00128 }
00129
00135 inline int int_(int input, int def=0)
00136 {
00137 return (input < -1000)? def : input;
00138 }
00139
00141 const ProgressLogger& logger_;
00142 };
00143
00144
00145
00146 template <typename MapType>
00147 const std::string ANDIHandler<MapType>::user_params_[] = {"ContactPosition",
00148 "ProcessingNumer", "ErrorLog", "CalibrationHistory", "NumOfCalibrations",
00149 "InstSerial", "InstComments", "InstSoftware", "InstFirmware", "InstOS", "InstID",
00150 "InletTemp", "IonModeAdd", "SrcTemp", "AccPot", "InstParams", "DetPot", "DetEntrPot"};
00151
00152 template <typename MapType>
00153 const std::string ANDIHandler<MapType>::description_[] = {"Position of the contact person",
00154 "number of times processed", "Processing Method error log", "history of calibration",
00155 "number of times calibrated", "Instrument serial number", "Instrument id comments",
00156 "Instrument software revision", "Instrument firmware revision",
00157 "Operating system revision", "Instrument ProteinIdentification code",
00158 "Spectrometer inlet temperature", "Additional ionization mode information",
00159 "Ionization source temperature", "Accelerating Potential",
00160 "Instrument parameter comments", "Detector potential", "Detector entrance potential"};
00161
00162 template <typename MapType>
00163 void ANDIHandler<MapType>::parse(std::string file)
00164 {
00165 if (file=="") return;
00166
00167 char* file_name = (char*) file.c_str();
00168
00169 std::ifstream infile(file_name);
00170 if (!infile)
00171 {
00172 throw Exception::FileNotFound(__FILE__, __LINE__, __PRETTY_FUNCTION__,file_name);
00173 }
00174 infile.close();
00175
00176 ncopts = 0;
00177 int file_id = ms_open_read(file_name);
00178
00179 MS_Admin_Data ms_admin;
00180 MS_Sample_Data ms_sample;
00181 MS_Test_Data ms_test;
00182 MS_Raw_Data_Global ms_raw_global;
00183 MS_Instrument_Data ms_inst;
00184
00185 if (file_id == MS_ERROR)
00186 {
00187 throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__,file_name,"Error: could not open ANDI/MS file. Invalid file!");
00188 }
00189
00190 ms_init_global( 0, &ms_admin, &ms_sample, &ms_test, &ms_raw_global);
00191
00192 if (ms_read_global( file_id, &ms_admin, &ms_sample, &ms_test, &ms_raw_global) == MS_ERROR)
00193 {
00194 throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__,file_name,"Error: could not read global data of ANDI/MS file. Invalid file!");
00195 }
00196
00197
00198 getAdminData_(&ms_admin);
00199 getSampleData_(&ms_sample);
00200 getTestData_(&ms_test);
00201
00202 long index;
00203 long num_scans = ms_raw_global.nscans;
00204 logger_.startProgress(0,num_scans,"reading ANDI/MS file");
00205 exp_.reserve(num_scans);
00206 long num_inst = ms_admin.number_instrument_components;
00207 ms_admin_expt_t expt_type = ms_admin.experiment_type;
00208 bool is_library = (expt_library == expt_type );
00209
00210 ms_init_instrument(0,&ms_inst);
00211 if (num_inst > 1) num_inst = 1;
00212 for (index = 0; index < num_inst; index++)
00213 {
00214 logger_.setProgress(index);
00215 ms_inst.inst_no = index;
00216
00217 if (ms_read_instrument( file_id, &ms_inst) == MS_ERROR)
00218 {
00219 std::cerr << "Warning: could not read instrument data of ANDI/MS file '" << file <<"'." << std::endl;
00220 }
00221 else
00222 {
00223
00224 getInstrumentData_(&ms_inst);
00225 }
00226
00227 ms_init_instrument(1,&ms_inst);
00228 }
00229 MS_Raw_Per_Scan ms_raw;
00230 MS_Raw_Library ms_lib;
00231
00232 int err_code;
00233
00234 ms_init_per_scan(0, &ms_raw, &ms_lib);
00235
00236 for (index=0; index<num_scans; index++)
00237 {
00238 ms_raw.scan_no = index;
00239
00240 if (is_library)
00241 {
00242 ms_lib.scan_no = index;
00243 err_code = ms_read_per_scan(file_id, &ms_raw, &ms_lib);
00244 }
00245 else
00246 {
00247 err_code = ms_read_per_scan(file_id, &ms_raw, NULL);
00248 }
00249
00250 if (err_code == MS_ERROR)
00251 {
00252 std::cerr << "Warning: could not read scan " << index << " of ANDI/MS file '" << file << "'." << std::endl;
00253 }
00254 else
00255 {
00256
00257 getRawPerScan_(&ms_raw,&ms_raw_global);
00258 }
00259
00260 ms_init_per_scan( 1, &ms_raw, &ms_lib);
00261 }
00262
00263 ms_init_global( 1, &ms_admin, &ms_sample, &ms_test, &ms_raw_global);
00264 ms_close( file_id);
00265 logger_.endProgress();
00266 }
00267
00268 template <typename MapType>
00269 void ANDIHandler<MapType>::getAdminData_(MS_Admin_Data* admin_data)
00270 {
00271
00272 std::string file = string_(admin_data->source_file_reference);
00273 int last_slash = file.rfind("/",file.size());
00274 int last_backslash = file.rfind("\\",file.size());
00275 int cut = (last_slash > last_backslash)? last_slash : last_backslash;
00276 exp_.getSourceFile().setNameOfFile( file.substr(cut+1) );
00277 exp_.getSourceFile().setPathToFile( file.substr(0,cut+1) );
00278
00279 exp_.getSourceFile().setFileType( string_(admin_data->source_file_format) );
00280
00281 ContactPerson contact;
00282 contact.setLastName( string_(admin_data->operator_name) );
00283 contact.setMetaValue(user_params_[CONTACT], String("Operator"));
00284 exp_.getContacts().push_back(contact);
00285
00286
00287 contact = ContactPerson();
00288 contact.setLastName( string_(admin_data->dataset_owner) );
00289 contact.setContactInfo( string_(admin_data->dataset_origin) );
00290 contact.setMetaValue(user_params_[CONTACT], String("Dataset owner"));
00291 exp_.getContacts().push_back(contact);
00292
00293 typedef ProcessingMethod pm;
00294
00295 int exp_map[] = {SpectrumSettings::PEAKS, SpectrumSettings::RAWDATA, 0};
00296 exp_.getProcessingMethod().setSpectrumType( (SpectrumSettings::SpectrumType) exp_map[admin_data->experiment_type - expt_centroid]);
00297
00298 exp_.getSoftware().setName( string_(admin_data->post_expt_program_name) );
00299 exp_.getProcessingMethod().setMetaValue(user_params_[ANDI_ERROR], string_(admin_data->error_log));
00300 exp_.getProcessingMethod().setMetaValue(user_params_[PROC], int_(admin_data->number_times_processed));
00301
00302 std::stringstream buffer;
00303 buffer << string_(admin_data->calibration_history_0) << string_(admin_data->calibration_history_1)
00304 << string_(admin_data->calibration_history_2) << string_(admin_data->calibration_history_3);
00305 exp_.getProcessingMethod().setMetaValue(user_params_[CALHIST], String(buffer.str()));
00306 exp_.getProcessingMethod().setMetaValue(user_params_[CALTIMES], int_(admin_data->number_times_calibrated));
00307
00308
00309
00310
00311
00312 }
00313
00314
00315 template <typename MapType>
00316 void ANDIHandler<MapType>::getSampleData_(MS_Sample_Data* sample_data)
00317 {
00318 std::stringstream buffer;
00319 if (sample_data->internal_id != NULL) buffer << sample_data->internal_id;
00320 if (sample_data->external_id != NULL) buffer << "(" << sample_data->external_id << ")";
00321 exp_.getSample().setNumber(buffer.str());
00322 exp_.getSample().setComment( string_(sample_data->comments) );
00323
00324
00325 int sample_map[] = {Sample::SOLID, Sample::LIQUID, Sample::GAS, 0, 0, 0, 0};
00326 exp_.getSample().setState( (Sample::SampleState) sample_map[sample_data->state - state_solid]);
00327
00328
00329
00330 }
00331
00332 template <typename MapType>
00333 void ANDIHandler<MapType>::getTestData_(MS_Test_Data* test_data)
00334 {
00335 exp_.getInstrument().setMetaValue(user_params_[INSTPARAMS], string_(test_data->comments));
00336
00337
00338
00339
00340
00341 typedef IonSource is;
00342 IonSource& src = exp_.getInstrument().getIonSource();
00343 int inlet_map[] = {is::MEMBRANESEPARATOR, 0, is::OPENSPLIT, is::JETSEPARATOR, is::DIRECT, is::SEPTUM,
00344 is::PARTICLEBEAM, is::RESERVOIR, is::MOVINGBELT, 0, is::FLOWINJECTIONANALYSIS, is::ELECTROSPRAYINLET,
00345 is::INFUSION, is::THERMOSPRAYINLET, 0, 0};
00346 src.setInletType( (is::InletType) inlet_map[test_data->ms_inlet - inlet_membrane]);
00347 src.setMetaValue(user_params_[INLETTEMP], float_(test_data->ms_inlet_temperature));
00348
00349
00350
00351
00352 int ion_map[] = {is::EI, is::CI, is::FAB, is::FD, is::FI, is::ESI,
00353 is::TSP, is::APCI, is::PD, is::LD, is::SI, is::TI, 0};
00354 src.setIonizationMethod( (is::IonizationMethod) ion_map[test_data->ionization_mode - ionization_ei]);
00355
00356 std::stringstream buffer;
00357 if (test_data->fab_type != NULL) buffer << "FABType=" << test_data->fab_type << " ";
00358 if (test_data->fab_matrix != NULL) buffer << "FABMatrix=" << test_data->fab_matrix << " ";
00359 if (test_data->reagent_gas != NULL) buffer << "ReagentGas=" << test_data->reagent_gas << " ";
00360 buffer << "ReagentGasPressure=" << test_data->reagent_gas_pressure << " ";
00361 buffer << "ElectronEnergy=" << test_data->electron_energy << " ";
00362 buffer << "LaserWaveLength=" << test_data->laser_wavelength << " ";
00363 buffer << "FilamentCurrent=" << test_data->filament_current << " ";
00364 buffer << "EmissionCurrent=" << test_data->emission_current << " ";
00365 src.setMetaValue(user_params_[IONMODEADD], String(buffer.str()));
00366 src.setMetaValue(user_params_[SRCTEMP], test_data->source_temperature);
00367 src.setMetaValue(user_params_[ACCPOT], test_data->accelerating_potential);
00368
00369 pol_ = (IonSource::Polarity) (test_data->ionization_polarity - polarity_plus + 1);
00370
00371
00372
00373 typedef IonDetector id;
00374 IonDetector& det = exp_.getInstrument().getIonDetector();
00375 int detector_map[] = {id::ELECTRONMULTIPLIER, id::PHOTOMULTIPLIER, id::FOCALPLANEARRAY, id::FARADAYCUP,
00376 id::CONVERSIONDYNODEELECTRONMULTIPLIER, id::CONVERSIONDYNODEPHOTOMULTIPLIER,
00377 id::MULTICOLLECTOR, 0};
00378 det.setType( (id::Type) detector_map[test_data->detector_type - detector_em]);
00379 det.setMetaValue(user_params_[DETPOT], float_(test_data->detector_potential));
00380 det.setMetaValue(user_params_[DETENTRPOT], float_(test_data->detector_entrance_potential));
00381
00382
00383
00384 typedef MassAnalyzer ma;
00385 ma analyzer;
00386
00387 int dir_map[] = {ma::UP, ma::DOWN, 0};
00388 analyzer.setScanDirection( (ma::ScanDirection) dir_map[test_data->scan_direction - direction_up]);
00389
00390
00391 int law_map[] = {ma::LINEAR, ma::EXPONENTIAL, ma::QUADRATIC, 0};
00392 analyzer.setScanLaw( (ma::ScanLaw) law_map[test_data->scan_law - law_linear]);
00393
00394
00395 int function_map[] = {ma::MASSSCAN, ma::SELECTEDIONDETECTION, 0};
00396 analyzer.setScanFunction( (ma::ScanFunction) function_map[test_data->scan_function - function_scan]);
00397
00398 analyzer.setResolutionType( (ma::ResolutionType) (test_data->resolution_type - resolution_constant));
00399 analyzer.setScanTime(test_data->scan_time);
00400
00401 if (test_data->resolution_method != NULL)
00402 {
00403 if (String(test_data->resolution_method) == "50% peak height")
00404 {
00405 analyzer.setResolutionMethod(ma::FWHM);
00406 }
00407 else
00408 {
00409 if (String(test_data->resolution_method) == "10% peak valley")
00410 {
00411 analyzer.setResolutionMethod(ma::TENPERCENTVALLEY);
00412 }
00413 }
00414 }
00415 exp_.getInstrument().getMassAnalyzers().push_back(analyzer);
00416
00417
00418
00419 }
00420
00421 template <typename MapType>
00422 void ANDIHandler<MapType>::getInstrumentData_(MS_Instrument_Data* inst_data)
00423 {
00424 exp_.getInstrument().setName( string_(inst_data->name) );
00425 exp_.getInstrument().setVendor( string_(inst_data->manufacturer) );
00426 exp_.getInstrument().setModel( string_(inst_data->model_number) );
00427
00428 exp_.getInstrument().setMetaValue(user_params_[INSTSERIAL], string_(inst_data->serial_number));
00429 exp_.getInstrument().setMetaValue(user_params_[INSTCOMMENTS], string_(inst_data->comments));
00430 exp_.getInstrument().setMetaValue(user_params_[INSTSOFTWARE], string_(inst_data->software_version));
00431 exp_.getInstrument().setMetaValue(user_params_[INSTFIRMWARE], string_(inst_data->firmware_version));
00432 exp_.getInstrument().setMetaValue(user_params_[INSTOS], string_(inst_data->operating_system));
00433 exp_.getInstrument().setMetaValue(user_params_[INSTID], string_(inst_data->id));
00434 }
00435
00436 template <typename MapType>
00437 void ANDIHandler<MapType>::getRawPerScan_(MS_Raw_Per_Scan* scan_data, MS_Raw_Data_Global* global_data)
00438 {
00439 float mass_factor = float_(global_data->mass_factor, 1.0f);
00440 float intens_factor = float_(global_data->intensity_factor, 1.0f);
00441 float intens_offset = float_(global_data->intensity_offset);
00442
00443
00444 if (mass_factor==0.0f) mass_factor = 1.0f;
00445 if (intens_factor==0.0f) intens_factor = 1.0f;
00446
00447
00448 if (global_data->has_masses!=1 || global_data->has_times==1)
00449 {
00450 return;
00451 }
00452
00453
00454 exp_.resize(exp_.size()+1);
00455
00456
00457 typename MapType::SpectrumType& spectrum = exp_.back();
00458 spectrum.resize(scan_data->points);
00459 spectrum.setRT( float_(scan_data->scan_acq_time));
00460 spectrum.setMSLevel(1);
00461 spectrum.getInstrumentSettings().setMzRangeStart(float_(scan_data->mass_range_min));
00462 spectrum.getInstrumentSettings().setMzRangeStop(float_(scan_data->mass_range_max));
00463 spectrum.getInstrumentSettings().setPolarity(pol_);
00464
00465
00466 std::string intensity_format = ms_enum_to_string(global_data->intensity_format);
00467 if (intensity_format!= "Short" && intensity_format!= "Long" && intensity_format!= "Float" && intensity_format!= "Double")
00468 {
00469 throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__,"","ANDI/MS file parse error. Unknown intensity format '"+intensity_format+"'.");
00470 }
00471 std::string mass_format = ms_enum_to_string(global_data->mass_format);
00472 if (mass_format!= "Short" && mass_format!= "Long" && mass_format!= "Float" && mass_format!= "Double")
00473 {
00474 throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__,"", "ANDI/MS file parse error. Unknown mass format '"+mass_format+"'.");
00475 }
00476
00477
00478 for (int i=0; i < scan_data->points; i++)
00479 {
00480
00481 double intensity(0);
00482 if (intensity_format == "Short") intensity = (double) ((short*) scan_data->intensities)[i];
00483 else if (intensity_format == "Long") intensity = (double) ((long*) scan_data->intensities)[i];
00484 else if (intensity_format == "Float") intensity = (double) ((float*) scan_data->intensities)[i];
00485 else if (intensity_format == "Double") intensity = ((double*) scan_data->intensities)[i];
00486 spectrum.getContainer()[i].setIntensity(intensity * intens_factor + intens_offset);
00487
00488
00489 double mass(0);
00490 if (mass_format == "Short") mass = (double) ((short*) scan_data->masses)[i];
00491 else if (mass_format == "Long") mass = (double) ((long*) scan_data->masses)[i];
00492 else if (mass_format == "Float") mass = (double) ((float*) scan_data->masses)[i];
00493 else if (mass_format == "Double") mass = ((double*) scan_data->masses)[i];
00494 spectrum.getContainer()[i].setPosition(mass * mass_factor);
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504 }
00505
00506 }
00507 }
00508
00509 #endif