Extract Peak heights from a series

Python
  1. """
  2. Version 3.0.3
  3.  
  4. Use this macro if you have assigned peaks for multiple spectra in a series and you want extract the peak heights.
  5.  
  6. This macro will update first the peak height, then will group all in a Pandas dataFrame for easy exporting to file.
  7.  
  8. The dataFrame has the following structure:
  9.  
  10.  
  11. | NR_ID | SP1 | SP2 | SP3
  12. H N | | | |
  13. -------------+-------- +-----------+-----------+---------
  14. 7.5 104.3 | A.1.ARG | 10 | 100 | 1000
  15.  
  16. Index: multiIndex => axisCodes as levels;
  17. Columns => NR_ID: ID for the nmrResidue(s) assigned to the peak if available
  18. Spectrum series values sorted by ascending values, if series values are not set, then the
  19. spectrum name is used instead.
  20. Cell values: heights (for this macro)
  21.  
  22. This dataframe is available from the SpectrumGroup class property `seriesPeakHeightForPosition`.
  23. N.B. this feature is still under development and can change or be deprecated in future releases.
  24.  
  25. Change the user input as needed.
  26.  
  27. """
  28.  
  29.  
  30. import pandas as pd
  31. from ccpn.core.lib.ContextManagers import undoBlock, undoBlockWithoutSideBar, notificationEchoBlocking
  32. from ccpn.core.lib.peakUtils import estimateVolumes, updateHeight
  33. from ccpn.ui.gui.widgets import MessageDialog
  34. from ccpn.ui.gui.popups.SpectrumGroupEditor import SpectrumGroupEditor
  35.  
  36. ##################################### User input ####################################
  37.  
  38. exportPath = `~/Desktop/`
  39. exportFileName = `myAnalysis.xlsx`
  40.  
  41. recalculateHeight = True
  42. recalculateVolume = False
  43.  
  44. spectrumGroupName = `MySpectrumGroup`
  45.  
  46. sortByDataByNR_ID = False # Sort table by NmrResidue ID. See below for more sorting options. (see Pandas docs for advanced settings)
  47. export = True # If you want export to other formats, change the file name and export command below.
  48.  
  49.  
  50. #################################### Start of the code ####################################
  51.  
  52. spectrumGroup = get(`SG:`+spectrumGroupName)
  53.  
  54. def _queryForNewSpectrumGroup(spectrumGroup=None):
  55.  
  56. msg = `This macro requires a SpectrumGroup containing spectra and defined series`
  57. if not spectrumGroup:
  58. needCreateNewSG = MessageDialog.showYesNo(`SpectrumGroup not found`,`%s. Create new?`% msg)
  59. if needCreateNewSG:
  60. sge = SpectrumGroupEditor(parent=mainWindow, mainWindow=mainWindow, editMode=False)
  61. sge.exec_()
  62. spectrumGroup = sge.obj
  63. if spectrumGroup.name != spectrumGroupName:
  64. warning(`The spectrumGroupName variable in this macro is different from the new spectrumGroup name.`
  65. `If you run this macro again it will prompt another Popup.`)
  66. else:
  67. raise RuntimeError(`SpectrumGroup not found. %s`% msg)
  68.  
  69. return spectrumGroup
  70.  
  71. while not spectrumGroup:
  72. spectrumGroup = _queryForNewSpectrumGroup(spectrumGroup)
  73.  
  74.  
  75. ######## Get the spectra from the spectrumGroup and their peaks from the last added peakList
  76. spectra = [sp for sp in spectrumGroup.spectra]
  77. peaks = [pk for sp in spectra for pk in sp.peakLists[-1].peaks]
  78. info(`Using peaks contained in the last peakList for spectra %s` % `, `.join(map(str, spectra)))
  79.  
  80. ######## Recalculate peak properties
  81. info(`Recalculating peak properties...`)
  82. with undoBlockWithoutSideBar():
  83. with notificationEchoBlocking():
  84. if recalculateHeight:
  85. list(map(lambda x: updateHeight(x), peaks))
  86. if recalculateVolume:
  87. list(map(lambda x: estimateVolumes(x), peaks))
  88. info(`Recalculating peak properties completed.`)
  89.  
  90. ######## Get dataframes for the spectrumGroup
  91. df = spectrumGroup.seriesPeakHeightForPosition
  92.  
  93. def naturalSort(df, col):
  94. df[`_int`] = df[col].str.extract(`(\d+)`)
  95. _nonIntDF = df[df[`_int`].isnull()]
  96. df = df[~df[`_int`].isnull()]
  97. df[`_int`] = df[`_int`].astype(int)
  98. df = df.sort_values(by=[`_int`])
  99. df = pd.concat([df, _nonIntDF])
  100. df.drop([`_int`], axis=1, inplace = True)
  101. return df
  102.  
  103. if sortByDataByNR_ID:
  104. df = naturalSort(df, `NR_ID`)
  105.  
  106. ## to sort by axis: e.g. H. The table will be sorted ascending for H ppm position
  107. # df = df.sort_index(level=`H`)
  108.  
  109. if export:
  110. df.to_excel(exportPath+exportFileName) # or use df.to_csv() for "file.csv" fileNames. etc
  111. info(`DataFrame exported in: %s` %exportPath+exportFileName)
  112.  
  113. print(df)


Hi, can you help to to run this macro? I hace copy-pasted this in my user macros but when I try to run it it continues asking me where is the Spectral group

Hi,
yes you need to have a spectrumGroup, spectra and peaks.
- On sidebar: create a new spectrumGroup by double click on <New SpectrumGroup>,
- add a name
- select the spectra of interest and add to the group with drag&drop accross the boxes,
- on the series tab, add the units
- save changes

- Open the macro editor from the menus.
- open your macro/or copy paste the above code to a new empty macro,
- modify line 44 spectrumGroupName = `MySpectrumGroup` to your spectrumGroup name defined in the popup
- modify the other user input as needed : such as
exportPath = `~/Desktop/`
exportFileName = `myAnalysis.xlsx`
- press the play button to start.

I hope it helps

Hi Luca,
I am just getting to grips with the command line, and not really getting very far with turning my scripts into macros. This is very similar to something I need. I can’t see where this macro gets the spectrum group name from. Do you have to define it in the macro? Is it possible to write a macro that queries (with a pop-up?) for the spectrum group (drag and drop?) and then ask for an output filename? Otherwise I can’t see the benefit of having macros over textfiles that I can paste into the command line.
Thanks
Matt

Hi, if you copy and paste all the macro in the MacroEditor and run, it should raise a popup asking to create aspectrumGroup if is not there yet.
Alternatively, you can create first the spectrumGroup from sidebar, with the series values (last tab), give it a name, and copy it in line 44 on the macroEditor.
The settings are from line 38 to 47…

OK, thanks, that helps. Do you have to name your new spectrum group MySpectrumGroup?

No, you can call it whatever you like and rename it at any time. Simply double-click on it in the sidebar to rename in the pop-up.
Vicky