Examples
The beautifuljason.examples package contains demonstration scripts showcasing practical usage of the BeautifulJASON API. These scripts are intended as a starting point and reference for developers integrating JASON automation into their workflows.
quick_start.py
A minimal example that loads a 1D 1H spectrum, performs multiplet analysis, customizes the visual appearance, and saves the result as a PNG image.
Highlights:
Runs without user configuration using bundled test data.
Shows how to apply analysis and customize graphics items.
Demonstrates document rendering and export to image.
Source code:
1##
2##-----------------------------------------------------------------------------
3##
4## Copyright (c) 2023 JEOL Ltd.
5## 1-2 Musashino 3-Chome
6## Akishima Tokyo 196-8558 Japan
7##
8## This software is provided under the MIT License. For full license information,
9## see the LICENSE file in the project root or visit https://opensource.org/licenses/MIT
10##
11##++---------------------------------------------------------------------------
12##
13## ModuleName : BeautifulJASON
14## ModuleType : Python API for JASON desktop application and JJH5 documents
15## Purpose : Automate processing, analysis, and report generation with JASON
16## Author : Nikolay Larin
17## Language : Python
18##
19####---------------------------------------------------------------------------
20##
21
22def main():
23 import os
24 import tempfile
25 import beautifuljason as bjason
26 from PIL import Image as PILImage
27
28 # Determine the path to the data directory inside the beautifuljason's tests subpackage
29 test_data_dir = os.path.join(os.path.dirname(bjason.__file__), 'tests', 'data')
30
31 # Specify input spectral file and define the path for the output PNG file
32 input_1H_file = os.path.join(test_data_dir, "Ethylindanone_Proton-13-1.jdf")
33 output_file = os.path.join(tempfile.gettempdir(), "Ethylindanone_Proton-13-1.png")
34
35 # Create an instance of the JASON application interface
36 jason = bjason.JASON()
37
38 # Define and customize the default font settings
39 font = bjason.base.Font.default_font()
40 font['family'] = 'Arial'
41 font['point_size'] = 12
42
43 # Load the 1H spectral file, apply multiplet analysis, and customize its visual appearance
44 with jason.create_document(input_1H_file, actions=[{'name': 'multiplet_analysis'}]) as doc:
45 # Access the first spectral item and adjust its properties
46 spec_item = doc.nmr_items[0]
47 spec_item.header = 'Ethylindanone'
48 spec_item.header_font = font
49 spec_item.x_font = font
50 spec_item.mult_intg_label_font = font
51 spec_item.peak_label_font = font
52 spec_item.plot_1d_color = '#3556d8'
53 spec_item.show_y_axis = False
54
55 # Save the customized document to an image file
56 jason.save(doc, output_file)
57
58 # Display the generated image using the default image viewer
59 image = PILImage.open(output_file)
60 image.show()
61
62if __name__ == '__main__':
63 main()
analyze_and_report.py
A more advanced batch script for automated report generation. Processes multiple input spectra, applies conditional analysis, adds parameter/peak/multiplet tables, customizes layout and appearance, inserts logos, and saves results in various formats.
Highlights:
Handles both 1H, 13C, and 2D NMR spectra with context-sensitive logic.
Generates publication-style multiplet reports for 1H spectra.
Adds parameter and peak tables, headers, and corporate branding.
Accepts multiple input/output files via command-line arguments.
Source code:
1##
2##-----------------------------------------------------------------------------
3##
4## Copyright (c) 2023 JEOL Ltd.
5## 1-2 Musashino 3-Chome
6## Akishima Tokyo 196-8558 Japan
7##
8## This software is provided under the MIT License. For full license information,
9## see the LICENSE file in the project root or visit https://opensource.org/licenses/MIT
10##
11##++---------------------------------------------------------------------------
12##
13## ModuleName : BeautifulJASON
14## ModuleType : Python API for JASON desktop application and JJH5 documents
15## Purpose : Automate processing, analysis, and report generation with JASON
16## Author : Nikolay Larin
17## Language : Python
18##
19####---------------------------------------------------------------------------
20##
21
22import argparse
23import os.path
24import datetime
25import beautifuljason as bjason
26
27# Custom column ID for the multiplet name column of the multiplet table.
28# The value must be negative and unique.
29ColID_NAME = -1
30
31def parse_arguments():
32 """Parse command line arguments."""
33 parser = argparse.ArgumentParser(
34 description='Batch process and analyze spectral files. The script performs automatic analysis of spectra, creates tables, reports, and modifies visual properties. The results are saved in the specified output files.',
35 usage='%(prog)s [-h] input_files [input_files ...] -o OUTPUT_FILES [OUTPUT_FILES ...]'
36 )
37 parser.add_argument('input_files', nargs='+', help='List of spectral files to process.')
38 parser.add_argument('-o', '--output-files', required=True, nargs='+', help='List of output files. Supported formats: .jjh5, .jjj, .jdx, and .pdf.')
39 return parser.parse_args()
40
41def customize_layout(doc: bjason.Document):
42 """Customize the layout of spectral items."""
43 for spec_item in doc.nmr_items:
44 old_item_pos = spec_item.pos
45 old_item_size = spec_item.size
46 spec_item.pos = (old_item_pos[0] + old_item_size[0] * 0.3, old_item_pos[1])
47 spec_item.size = (old_item_size[0] * 0.7, old_item_size[1] * 0.9)
48
49def customize_appearance(doc: bjason.Document):
50 """Customize the appearance of spectral items."""
51 for spec_item in doc.nmr_items:
52 spec_data = spec_item.spec_data(0)
53 spec_item.show_y_axis = spec_data.ndim != 1
54 spec_item.plot_1d_color = '#006400'
55
56def add_parameter_tables(doc: bjason.Document):
57 """Add parameter tables and adjust their layout."""
58 for spec_item in doc.nmr_items:
59 spec_data = spec_item.spec_data(0)
60 params_item = doc.create_params_table(spec_item, spec_data)
61 params_item.param_list.append([
62 {'name': 'Filename', 'value': os.path.basename(spec_data.raw_data.spec_info.get_param('OrigFilename'))},
63 {'name': 'Nuclide', 'value': spec_data.spec_info.nuclides[0] if len(spec_data.spec_info.nuclides) == 1 else ', '.join(spec_data.spec_info.nuclides)},
64 {'name': 'Solvent', 'value': spec_data.raw_data.spec_info.get_param('Solvent')}
65 ])
66 spec_item_pos = spec_item.pos
67 spec_item_size = spec_item.size
68 new_x = spec_item_pos[0] - 3.0/7.0*spec_item_size[0]
69 params_item.pos = (new_x, spec_item_pos[1])
70 params_item.size = (spec_item_pos[0] - new_x, spec_item_size[1] * 0.3)
71
72def add_peak_and_multiplet_tables(doc: bjason.Document):
73 """Add peak and/or multiplet tables and adjust their layout. The multilet tables are created for 1H spectra only."""
74 for spec_item in doc.nmr_items:
75 spec_data = spec_item.spec_data(0)
76 table_item: bjason.NMRPeakTableGraphicsItem | bjason.NMRMultipletTableGraphicsItem = None
77 if spec_data.ndim == 1:
78 if spec_data.spec_info.nuclides[0] == '1H':
79 table_item = doc.create_nmrmultiplets_table(spec_item, spec_data)
80 ColID = bjason.NMRMultipletTableGraphicsItem.ColumnID
81 # Define visible columns and their order. Negative numbers correspond to custom columns.
82 table_item.visual_column_ids = (ColID_NAME, ColID.START0, ColID.END0, ColID.PEAKS_VOLUME, ColID.NORMALIZED)
83 # Customize standard columns view
84 table_item.customized_columns.append((
85 {'Type': ColID.START0, 'Digits': 2},
86 {'Type': ColID.END0, 'Digits': 2},
87 {'Type': ColID.NORMALIZED, 'Digits': 1},
88 {'Type': ColID_NAME, 'Digits': -1, 'CustomTitle': 'Name'}
89 ))
90 if not table_item:
91 table_item = doc.create_nmrpeaks_table(spec_item, spec_data)
92 ColID = bjason.NMRPeakTableGraphicsItem.ColumnID
93 if spec_data.ndim == 1:
94 table_item.visual_column_ids = [ColID.POS0, ColID.WIDTH0, ColID.HEIGHT, ColID.VOLUME]
95 elif spec_data.ndim == 2:
96 table_item.visual_column_ids = [ColID.POS0, ColID.POS1, ColID.HEIGHT, ColID.VOLUME]
97 table_item.show_title = True
98 table_item.alternating_row_colors = True
99 spec_item_pos = spec_item.pos
100 spec_item_size = spec_item.size
101 new_x = spec_item_pos[0] - 3.0/7.0*spec_item_size[0]
102 table_item.pos = (new_x, spec_item_pos[1] + spec_item_size[1] * 0.3)
103 table_item.size = (spec_item_pos[0] - new_x, spec_item_size[1] * 0.7)
104
105def add_headers_and_logos(doc: bjason.Document):
106 """Add headers and logos to the document."""
107 logo_width = 200.0
108 logo_image_data = None
109 for spec_item in doc.nmr_items:
110 spec_item.show_header = False
111 text_item = doc.create_text_item()
112 text_item.pos = spec_item.pos
113 text_item.size = (spec_item.size[0], 60.0)
114 text_item.text.html = '<b>{}</b><br/>Copyright (C) My Company. All rights reserved'.format(datetime.datetime.now().isoformat(timespec='seconds'))
115 spec_item.pos = (spec_item.pos[0], text_item.pos[1] + text_item.size[1])
116 if logo_image_data is None:
117 logo_image_data = doc.create_image_data(os.path.abspath(os.path.join(os.path.dirname(__file__), 'JEOL_company_logo.png')))
118 image_item = doc.create_image_item(logo_image_data.id)
119 image_item.pos = (text_item.pos[0] + text_item.size[0] - logo_width, text_item.pos[1])
120 image = image_item.image
121 image_item.size = (logo_width, logo_width * image.height / image.width)
122
123def add_multiplet_reports(doc):
124 """Add multiplet reports to the document. The multiplet reports are created for 1H spectra only."""
125 for spec_item in doc.nmr_items:
126 spec_data = spec_item.spec_data(0)
127 if spec_data.ndim == 1 and spec_data.spec_info.nuclides[0] == '1H':
128 report_item = doc.create_nmrmultiplet_report(spec_item, spec_data)
129 report_item.journal_format = 'Wiley'
130 report_item.pos = spec_item.pos
131 report_item.size = (0.5 * spec_item.size[0], 0.25 * spec_item.size[1])
132
133def apply_analysis(jason, doc):
134 """
135 Apply specific analysis techniques based on the type of spectrum.
136 Specifically, the script performs multiplet analysis for 1H spectra and peak picking for 13C and 2D spectra.
137 """
138 items_1H = []
139 items_13C = []
140 items_2D = []
141 for spec_item in doc.nmr_items:
142 spec_data = spec_item.spec_data(0)
143 if spec_data.ndim == 2:
144 items_2D.append(spec_item.id)
145 elif spec_data.ndim == 1:
146 if spec_data.spec_info.nuclides[0] == '1H':
147 items_1H.append(spec_item.id)
148 elif spec_data.spec_info.nuclides[0] == '13C':
149 items_13C.append(spec_item.id)
150
151 # Apply analysis actions to the document
152 jason.apply_actions(doc, [{'name': 'multiplet_analysis', 'items': items_1H}, {'name': 'peak_picking', 'items': items_13C + items_2D}])
153 for item in doc.items:
154 if item.type == bjason.GraphicsItem.Type.NMRMultipletTable:
155 # Add custom multiplet names to the Name column of the multiplet table
156 table_item: bjason.NMRMultipletTableGraphicsItem = item
157 for i, multiplet in enumerate(item.spec_data.multiplets):
158 table_item.set_custom_value(multiplet.id, ColID_NAME, f'M{i+1}')
159
160def main():
161 """Main entry point of the script."""
162 jason = bjason.JASON() # Create a JASON object
163 args = parse_arguments() # Parse command line arguments
164
165 # Convert input and output file paths to absolute paths
166 absolute_input_files = [os.path.abspath(file) for file in args.input_files]
167 absolute_output_files = [os.path.abspath(file) for file in args.output_files]
168
169 with jason.create_document(absolute_input_files) as doc: # Open and process the spectral files in JASON
170 customize_layout(doc) # Customize the layout of spectral items
171 customize_appearance(doc) # Customize the appearance of spectral items
172 add_parameter_tables(doc) # Add parameter tables and adjust their layout
173 add_peak_and_multiplet_tables(doc) # Add peak and/or multiplet tables and adjust their layout
174 add_headers_and_logos(doc) # Add headers and logos to the document
175 add_multiplet_reports(doc) # Add multiplet reports to the document
176 apply_analysis(jason, doc) # Apply specific analysis techniques based on the type of spectrum
177 jason.save(doc, absolute_output_files) # Save the document to the specified output files
178
179 # Optionally, open the resulting .jjh5 file in JASON for visual inspection
180 jjh5_files = [output_file for output_file in absolute_output_files if output_file.endswith('.jjh5')]
181 if jjh5_files:
182 jason.launch(jjh5_files)
183
184if __name__ == "__main__":
185 main()
These examples are intended to be self-contained and modifiable. Users are encouraged to adapt them to their own datasets and requirements.