99using CompMs . MsdialCore . DataObj ;
1010using CompMs . MsdialCore . Parameter ;
1111using CompMs . MsdialCore . Utility ;
12+ using NCDK ;
13+ using NCDK . IO ;
14+ using NCDK . Layout ;
15+ using NCDK . Smiles ;
1216using System ;
1317using System . Collections . Generic ;
18+ using System . Globalization ;
1419using System . IO ;
1520using System . Linq ;
1621using System . Text ;
@@ -34,6 +39,9 @@ public static void SaveSpectraTable(
3439 case ExportSpectraFileFormat . mgf :
3540 SaveSpectraTableAsMgfFormat ( exportStream , chromPeakFeature , scan . Spectrum ) ;
3641 break ;
42+ case ExportSpectraFileFormat . sdf :
43+ SaveSpectraTableAsSdfFormat ( exportStream , chromPeakFeature , scan . Spectrum , true , true ) ;
44+ break ;
3745 case ExportSpectraFileFormat . mat :
3846 SaveSpectraTableAsMatFormat ( exportStream , chromPeakFeature , scan . Spectrum , spectrumList , mapper , parameter ) ;
3947 break ;
@@ -53,14 +61,18 @@ public static void SaveSpectraTable(
5361 IMSScanProperty scan ,
5462 DataBaseMapper mapper ,
5563 ParameterBase parameter ,
56- AlignmentSpotProperty isotopeTrackedLastSpot = null ) {
64+ AlignmentSpotProperty isotopeTrackedLastSpot = null )
65+ {
5766 switch ( spectraFormat ) {
5867 case ExportSpectraFileFormat . msp :
5968 SaveSpectraTableAsNistFormat ( exportStream , spotProperty , scan . Spectrum , mapper , parameter ) ;
6069 break ;
6170 case ExportSpectraFileFormat . mgf :
6271 SaveSpectraTableAsMgfFormat ( exportStream , spotProperty , scan . Spectrum ) ;
6372 break ;
73+ case ExportSpectraFileFormat . sdf :
74+ SaveSpectraTableAsSdfFormat ( exportStream , spotProperty , scan . Spectrum , true , true ) ;
75+ break ;
6476 case ExportSpectraFileFormat . mat :
6577 SaveSpectraTableAsMatFormat ( exportStream , spotProperty , scan . Spectrum , mapper , parameter , isotopeTrackedLastSpot ) ;
6678 break ;
@@ -308,6 +320,152 @@ private static void WriteChromXFieldAsMGF(
308320 }
309321 #endregion
310322
323+ #region sdf
324+ public static void SaveSpectraTableAsSdfFormat (
325+ Stream stream ,
326+ AlignmentSpotProperty spotProperty ,
327+ IEnumerable < ISpectrumPeak > spectrum ,
328+ bool exportNoMs2Molecule ,
329+ bool Set2dCoordinates
330+ )
331+ {
332+ if ( ! exportNoMs2Molecule && ! spotProperty . IsMsmsAssigned )
333+ {
334+ return ;
335+ }
336+ var sb = new StringBuilder ( 8 * 1024 ) ;
337+ if ( spotProperty . IsMsmsAssigned )
338+ {
339+ MolBlockFromSmiles ( sb , spotProperty . SMILES , Set2dCoordinates ) ;
340+ }
341+ else
342+ {
343+ EmptyMolBlock ( sb ) ;
344+ }
345+ WriteChromPeakFeatureInfoAsSdf ( sb , spotProperty , spectrum ) ;
346+ sb . AppendLine ( "$$$$" ) ;
347+ sb . AppendLine ( ) ;
348+ var bytes = Encoding . ASCII . GetBytes ( sb . ToString ( ) ) ;
349+ stream . Write ( bytes , 0 , bytes . Length ) ;
350+ }
351+ public static void SaveSpectraTableAsSdfFormat (
352+ Stream stream ,
353+ ChromatogramPeakFeature chromPeakFeature ,
354+ IEnumerable < ISpectrumPeak > spectrum ,
355+ bool exportNoMs2Molecule ,
356+ bool Set2dCoordinates
357+ )
358+ {
359+ if ( ! exportNoMs2Molecule && ! chromPeakFeature . IsMsmsContained )
360+ {
361+ return ;
362+ }
363+ var sb = new StringBuilder ( 8 * 1024 ) ;
364+ if ( chromPeakFeature . IsMsmsContained )
365+ {
366+ MolBlockFromSmiles ( sb , chromPeakFeature . SMILES , Set2dCoordinates ) ;
367+ }
368+ else
369+ {
370+ EmptyMolBlock ( sb ) ;
371+ }
372+ WriteChromPeakFeatureInfoAsSdf ( sb , chromPeakFeature , spectrum ) ;
373+ sb . AppendLine ( "$$$$" ) ;
374+ sb . AppendLine ( ) ;
375+ var bytes = Encoding . ASCII . GetBytes ( sb . ToString ( ) ) ;
376+ stream . Write ( bytes , 0 , bytes . Length ) ;
377+ }
378+ private static void WriteSdfDataItem ( StringBuilder sb , string fieldName , string value )
379+ {
380+ sb . AppendLine ( "> <" + fieldName + ">" ) ;
381+ sb . AppendLine ( value ?? string . Empty ) ;
382+ }
383+ private static void EmptyMolBlock ( StringBuilder sb )
384+ {
385+ sb . AppendLine ( "" ) ;
386+ sb . AppendLine ( " MS-DIAL" ) ;
387+ sb . AppendLine ( ) ;
388+ sb . AppendLine ( " 0 0 0 0 0 0 999 V2000" ) ;
389+ sb . AppendLine ( "M END" ) ;
390+
391+ }
392+ private static void MolBlockFromSmiles ( StringBuilder sb , string smiles , bool Set2dCoordinates )
393+ {
394+ var sp = new SmilesParser ( ) ;
395+ IAtomContainer mol = sp . ParseSmiles ( smiles ) ;
396+ var sdg = new StructureDiagramGenerator
397+ {
398+ Molecule = mol
399+ } ;
400+ if ( Set2dCoordinates )
401+ {
402+ sdg . GenerateCoordinates ( ) ;
403+ }
404+ mol = sdg . Molecule ;
405+ using var tw = new StringWriter ( sb , CultureInfo . InvariantCulture ) ;
406+ using ( var w = new MDLV2000Writer ( tw ) )
407+ {
408+ w . Write ( mol ) ;
409+ } ;
410+ }
411+ private static void WriteChromPeakFeatureInfoAsSdf (
412+ StringBuilder sb ,
413+ AlignmentSpotProperty spotProperty ,
414+ IEnumerable < ISpectrumPeak > spectrum )
415+ {
416+ WriteSdfDataItem ( sb , "NAME" , string . IsNullOrWhiteSpace ( spotProperty . Name ) ? "Unknown" : spotProperty . Name ) ;
417+ WriteSdfDataItem ( sb , "SCANS" , spotProperty . MasterAlignmentID . ToString ( ) ) ;
418+ WriteSdfDataItem ( sb , "PRECURSOR MZ" , Math . Round ( spotProperty . MassCenter , 5 ) . ToString ( ) ) ;
419+ WriteSdfDataItem ( sb , "ION MODE" , spotProperty . IonMode . ToString ( ) ) ;
420+
421+ if ( spotProperty . IsMsmsAssigned )
422+ {
423+ if ( spotProperty . AdductType != null ) WriteSdfDataItem ( sb , "PRECURSOR TYPE" , spotProperty . AdductType . AdductIonName ) ;
424+ if ( ! string . IsNullOrWhiteSpace ( spotProperty . Formula . FormulaString ) ) WriteSdfDataItem ( sb , "FORMULA" , spotProperty . Formula . FormulaString ) ;
425+ if ( ! string . IsNullOrWhiteSpace ( spotProperty . InChIKey ) ) WriteSdfDataItem ( sb , "FORMULA" , spotProperty . InChIKey ) ;
426+ if ( ! string . IsNullOrWhiteSpace ( spotProperty . SMILES ) ) WriteSdfDataItem ( sb , "FORMULA" , spotProperty . SMILES ) ;
427+ WriteSdfDataItem ( sb , "MS LEVEL" , "MS2" ) ;
428+ var peaks = spectrum . Where ( spec => spec . Intensity > 0 ) . ToList ( ) ;
429+ WriteSdfDataItem ( sb , "NUM PEAKS" , peaks . Count . ToString ( ) ) ;
430+ var peaksText = string . Join (
431+ "\n " ,
432+ spectrum . Select ( p =>
433+ $ "{ Math . Round ( p . Mass , 5 ) } { Math . Round ( p . Intensity , 0 ) } "
434+ )
435+ ) ;
436+ WriteSdfDataItem ( sb , "MASS SPECTRAL PEAKS" , peaksText ) ;
437+ }
438+ }
439+ private static void WriteChromPeakFeatureInfoAsSdf (
440+ StringBuilder sb ,
441+ ChromatogramPeakFeature spotProperty ,
442+ IEnumerable < ISpectrumPeak > spectrum )
443+ {
444+ WriteSdfDataItem ( sb , "NAME" , string . IsNullOrWhiteSpace ( spotProperty . Name ) ? "Unknown" : spotProperty . Name ) ;
445+ WriteSdfDataItem ( sb , "SCANS" , spotProperty . PeakID . ToString ( ) ) ;
446+ WriteSdfDataItem ( sb , "PRECURSOR MZ" , Math . Round ( spotProperty . PrecursorMz , 5 ) . ToString ( ) ) ;
447+ WriteSdfDataItem ( sb , "ION MODE" , spotProperty . IonMode . ToString ( ) ) ;
448+
449+ if ( spotProperty . IsMsmsContained )
450+ {
451+ if ( spotProperty . AdductType != null ) WriteSdfDataItem ( sb , "PRECURSOR TYPE" , spotProperty . AdductType . AdductIonName ) ;
452+ if ( ! string . IsNullOrWhiteSpace ( spotProperty . Formula . FormulaString ) ) WriteSdfDataItem ( sb , "FORMULA" , spotProperty . Formula . FormulaString ) ;
453+ if ( ! string . IsNullOrWhiteSpace ( spotProperty . InChIKey ) ) WriteSdfDataItem ( sb , "FORMULA" , spotProperty . InChIKey ) ;
454+ if ( ! string . IsNullOrWhiteSpace ( spotProperty . SMILES ) ) WriteSdfDataItem ( sb , "FORMULA" , spotProperty . SMILES ) ;
455+ WriteSdfDataItem ( sb , "MS LEVEL" , "MS2" ) ;
456+ var peaks = spectrum . Where ( spec => spec . Intensity > 0 ) . ToList ( ) ;
457+ WriteSdfDataItem ( sb , "NUM PEAKS" , peaks . Count . ToString ( ) ) ;
458+ var peaksText = string . Join (
459+ "\n " ,
460+ spectrum . Select ( p =>
461+ $ "{ Math . Round ( p . Mass , 5 ) } { Math . Round ( p . Intensity , 0 ) } "
462+ )
463+ ) ;
464+ WriteSdfDataItem ( sb , "MASS SPECTRAL PEAKS" , peaksText ) ;
465+ }
466+ }
467+ #endregion
468+
311469 #region mat
312470 private static void SaveSpectraTableAsMatFormat (
313471 Stream stream ,
0 commit comments