c699util User's Guide
Similar to Introduction to the 699 Python Library, this article is a high-level description of c699util, intended for those who are only using it to write Python scripts. I do not describe low level c699util details here. For that, see the c699util developer's guide.
c699util is a Python module which provides housekeeping and science data extraction routines for MOMA telemetry files. Its interface is very similar to 699util's tmread module:
#!/usr/bin/env python3#==============================================================================# Packet data extraction through 699util's tmread module:#==============================================================================import tmreadtmfile = tmread.get_tmfile('/Users/mpallone/momadata/fm/2016-01-15-14.06.47-30410-MSFUNC/tm.mom.m3.s3')wrp_current_datapoints = []wrp_current_hkid = 800pkt_17_count = 0for pkt in tmfile(17):pkt_17_count += 1wrp_current_datapoints.extend(pkt[wrp_current_hkid])# Print out the data:print("pkt_17_count:", pkt_17_count)print()print("WRP current sample timestamp, WRP current sample science value:")for timestamp, value in wrp_current_datapoints:print(timestamp, '\t', value)#==============================================================================# Packet data extraction through c699util:#==============================================================================import c699utilc_tmfile = c699util.construct_tmfile('/Users/mpallone/momadata/fm/2016-01-15-14.06.47-30410-MSFUNC/tm.mom.m3.s3')wrp_current_datapoints = []wrp_current_hkid = 800pkt_17_count = 0for pkt in c_tmfile(17):pkt_17_count += 1wrp_current_datapoints.extend(pkt[wrp_current_hkid])# Print out the data:print("pkt_17_count:", pkt_17_count)print()print("WRP current sample timestamp, WRP current sample science value:")#for timestamp, value in wrp_current_datapoints:# print(timestamp, '\t', value)# Note the change here!for datapoint in wrp_current_datapoints:print(datapoint.relative_timestamp, '\t', datapoint.value)
As this example illustrates, some minor interface differences exist between c699util and tmread, which are documented at the end of this article.
You are highly encouraged to follow the following convention: if you use c699util in a Python script, please prefix it with "c_". For example, when I ported ioncount.py over to c699util, I made a copy of ioncount.py, called it c_ioncount.py, and then replaced tmread code with similar c699util code. This way, both scripts are available to run (a nice option to have if we encounter bugs), and we always know which underlying library we're using.
If we already have tmread, why bother with c699util?
Well, for one, c699util is about an order of magnitude faster than tmread (and sometimes more -- c_ioncount.py was 39x faster than ioncount.py when extracting selected ion counts).
More importantly, much of tmread is deprecated for MOMA. Any feature that tmread shares with c699util is no longer maintained. Instead of maintaining telemetry extraction libraries in C++, and then duplicating the exact same functionality in Python, we've decided to simply add a Python interface to the C++ code. This dramatically simplifies feature implementation, eliminates consistency issues between various tools, and speeds up software development and program run time, but it also means that tmread won't output data as accurately as c699util, and also won't have as many features.
c699util Flaw -- only one TMFile at a time
Because the C++ code around which c699util wraps frequently uses singletons, c699util can only operate on one TMFile at a time. Calling c699util.construct_tmfile() will invalidate any previously existing c699util.TMFile objects.
We rarely ever (if at all) need this capability, but when the C++ and c699util code is ported over to future missions, this design should be reconsidered.
Obtaining c699util
If you do not have the 699 Python tools installed on your computer, then the developer instructions in Python_Tool_Installation should work, although it's probably best to just ask a MOMA software developer to do it for you. Be sure to install Python 3.4.3 from the Python website.
If you already have 699 Python tools installed, you will probably also have to ask a MOMA software developer to setup c699util. Most likely, Python 3.4.3 will need to be installed directly from the website (sorry, Homebrew aficionados), and your virtual environment will need to be rebuilt so that it uses Python 3.4.3. However, if you happen to already be using Python 3.4.3, then SSH tunneling into repos699 and then updating ~/config699 and ~/labcode/699util should be all that you need to do to start using c699util.
TMFile
c699util provides a TMFile class which is very similar to tmread's TMFile class. c699util.TMFile objects can be obtained as follows:
import c699utilc_tmfile = c699util.get_tmfile('/Users/mpallone/momadata/fm/2016-01-15-14.06.47-30410-MSFUNC/tm.mom.m3.s3')
c699util.get_tmfile() is a thin wrapper around tmread.get_tmfile(), so it does all of the telemetry-file-finding-magic that tmread.get_tmfile() does:
import c699utilc_tmfile = c699util.get_tmfile() # grab the tm.mom file in the cwdc_tmfile = c699util.get_tmfile(12345) # Grab TID 12345c_tmfile = c699util.get_tmfile("/Users/mpallone/momadata/fm/2016-01-15-14.06.47-30410-MSFUNC") # Grab the tm.mom file in the specified directory
It would be preferable to not use the deprecated tmread module, but it seems unlikely to me that I'll ever get around to implementing get_tmfile()'s magic inside of c699util, at least on MOMA. Also, this tactic allows us to keep using the extremely useful TMArgumentParser class.
If tmread is not available, c699util.construct_tmfile() can be used:
import c699utilc_tmfile = c699util.construct_tmfile('/Users/mpallone/momadata/fm/2016-01-15-14.06.47-30410-MSFUNC/tm.mom.m3.s3')
Also, note the convention of using c_tmfile. I prefer to use 'tmfile' for tmread.TMFile objects, and 'c_tmfile' for c699util.TMFile objects, so that I can tell at a glance what kind of object I'm using. I strongly recommend that other script writers do the same.
Other useful methods:
#!/usr/bin/env python3import tmread, c699utiltmfile = tmread.get_tmfile(30410) # Give it a TID and let it find the file for usc_tmfile = c699util.construct_tmfile(tmfile.filename)
# (alternatively, we could just do c_tmfile = c699util.get_tmfile(30410)print("Absolute filename:", c_tmfile.filename())print("Absolute filename:", str(c_tmfile))# Absolute filename: /Users/mpallone/momadata/fm/2016-01-15-14.06.47-30410-MSFUNC/tm.mom.m3.s3print("Absolute directory:", c_tmfile.absolute_directory())# Absolute directory: /Users/mpallone/momadata/fm/2016-01-15-14.06.47-30410-MSFUNC# Parsed from the first GSE packet in the tm.mom file:print("TID Directory name:", c_tmfile.directory_string())# TID Directory name: 2016-01-15-14.06.47-30410-MSFUNCprint("Mass calibration file used:", c_tmfile.get_mcal_filename())# Mass calibration file used: 2016-01-17-23.48.39-30410.mcalprint("File size in bytes:", c_tmfile.file_size())# File size in bytes: 48384623print("TID:", c_tmfile.tid())# TID: 30410print("t0 in Unix time:", c_tmfile.t0_in_unix_time())# t0 in Unix time: 1452884878.3959727print("Number of packets:", c_tmfile.length())print("Number of packets:", len(c_tmfile))# Number of packets: 70232print("TMFile actually exists on the filesystem:", c_tmfile.exists())print("TMFile actually exists on the filesystem:", bool(c_tmfile))# TMFile actually exists on the filesystem: Truepkt_at_index_10 = c_tmfile.get_pkt(10)pkt_at_index_10 = c_tmfile[10]# We can iterate through c_tmfile and get packet objects:pkt_count = 0for pkt in c_tmfile:pkt_count += 1# The old tm_filter routines also work for c699util:pkt_17_count = 0for pkt in c_tmfile(17):pkt_17_count += 1pkt_count = 0for pkt in c_tmfile(type_filter=17, # Only yield packets of type 17marker_filter=2500, # Only yield packets at marker 2500start_time=1000, # Relative time = 1000 secondsstop_time=2000): # Relative time = 2000 secondspkt_count += 1# If the directory name is# '2016-01-15-14.06.47-30410-MSFUNC'# then the test name is# 'MSFUNC'print("Test name:", c_tmfile.test_name())# tmread.MessageLog is not deprecated, and is fully compatible with c699util:msg_log = c_tmfile.message_log()meta_markers = c_tmfile.get_meta_markers()for meta_marker in meta_markers:print(meta_marker.startRelativeTimeInSecs)print(meta_marker.endRelativeTimeInSecs)print(meta_marker.metaMarkerId)print(meta_marker.index)print(meta_marker.msg)print("model:", c_tmfile.model())# model: fmprint("FSW timestamp at of t0 packet:", c_tmfile.t0_in_sclk())# FSW timestamp at of t0 packet: 19351744
tmread.extract_tmfields() is compatible with c699util.TMFile objects:
#!/usr/bin/env python3import tmread, c699utiltmfile = tmread.get_tmfile(30410) # Give it a TID and let it find the file for usc_tmfile = c699util.construct_tmfile(tmfile.filename)AUX_AMP_DAC_SET_HKID = 61RF_AMP_MON_HKID = 62fields = tmread.extract_tmfields(c_tmfile, [AUX_AMP_DAC_SET_HKID, RF_AMP_MON_HKID])# Note that we still get c699util.TMDatapoint objects here, which are different# from 699util's tmread datapoints!sum_ = 0count = 0for datapoint in fields[RF_AMP_MON_HKID]:relative_timestamp = datapoint.relative_timestampunix_timestamp = datapoint.unix_timestampraw_timestamp = datapoint.fsw_timestampsum_ += datapoint.valuecount += 1if count != 0:print("RF Amp mon avg:", sum_ / count)## TMPacket
Just like TMFile, c699util provides TMPacket objects which are very similar to tmread.TMPacket objects:
#!/usr/bin/env python3import tmread, c699utiltmfile = tmread.get_tmfile(30410) # Give it a TID and let it find the file for usc_tmfile = c699util.construct_tmfile(tmfile.filename)gse_pkt = c_tmfile[0] # Pkt type 8, GSE generatedpkt_22 = c_tmfile[65] # Pkt type 22msg_log_pkt = c_tmfile[85] # Pkt type 8print("Unmasked type of gse_pkt:", gse_pkt.full_type())# Unmasked type of gse_pkt: 136print("Unmasked type of pkt_22:", pkt_22.full_type())# Unmasked type of pkt_22: 22# This is analagous to tmread.TMPacket.typeprint("gse_pkt with gse-generated bit masked out:", gse_pkt.get_type())# gse_pkt with gse-generated bit masked out: 8print("pkt_22 length, including header and checksum:", pkt_22.total_length())# pkt_22 length, including header and checksum: 224print("pkt_22 length, just the data:", pkt_22.length())# pkt_22 length, just the data: 212print("pkt_22 checksum:", pkt_22.checksum())print("pkt_22 checksum:", hash(pkt_22))# pkt_22 checksum: 1379474455print("Is pkt_22 gse created?", pkt_22.gse_created())# Is pkt_22 gse created? Falseprint("Is gse_pkt gse created?", gse_pkt.gse_created())# Is gse_pkt gse created? Trueprint("pkt_22 sequence number:", pkt_22.sequence())# pkt_22 sequence number: 146# Yes, I'm aware that 'sclk' is a misnomerprint("pkt_22 FSW timestamp:", pkt_22.sclk())# pkt_22 FSW timestamp: 19540225print("pkt_22 FSW timestamp, in seconds:", pkt_22.sclk_in_seconds())# pkt_22 FSW timestamp, in seconds: 1954.0225print("pkt_22 index:", pkt_22.index())# pkt_22 index: 65print("pkt_22 marker ID:", pkt_22.marker_id())# pkt_22 marker ID: 0# Packets before the first marker packet have a marker index of 0print("pkt_22 marker index:", pkt_22.xina_marker_index())# pkt_22 marker index: 0print("pkt_22 unix timestamp, in seconds:", pkt_22.unix_timestamp())# pkt_22 unix timestamp, in seconds: 1452884897.2440727print("pkt_22 relative timestamp, in seconds:", pkt_22.relative_timestamp())# pkt_22 relative timestamp, in seconds: 18.848099946975708print("pkt_22 marker text:", pkt_22.marker_text())# pkt_22 marker text: <no marker text, but you get the idea>############################################################# (this doesn't actually work for TID 30410, but I think you get the picture)## HKID 100 = phase cycle readback HKIDphase_cycle_readback_raw_data = pkt_22.all_raw_data(100)phase_cycle_readback_eng_data = pkt_22.all_eng_data(100)phase_cycle_readback_sci_data = pkt_22.all_data(100)phase_cycle_readback_sci_data = pkt[100]datapoint = phase_cycle_readback_sci_data[0]print("Datapoint unix timestamp, in seconds:", datapoint.unix_timestamp)print("Datapoint relative timestamp, in seconds:", datapoint.relative_timestamp)print("Datapoint value:", datapoint.value)first_phase_cycle_readback_science_sample = pkt_22.get_first_value(100)#############################################################print("Does gse_pkt have an earlier timestamp than pkt_22?", gse_pkt < pkt_22)# Does gse_pkt have an earlier timestamp than pkt_22? Trueprint("Raw message log:", msg_log_pkt.raw_message())print("Sanitized message log:", msg_log_pkt.message())# (output omitted for brevity)print("raw bytes:", pkt_22.raw_packet())# b'\x16\x92\x00\xd4\x01*x16x92x00xd4x01*)\x01\xfa\xf3x01xfaxf3\x02\x00.x02x00...(etc).meta_markers = pkt_22.get_meta_markers()for meta_marker in meta_markers:print(meta_marker.startRelativeTimeInSecs)print(meta_marker.endRelativeTimeInSecs)print(meta_marker.metaMarkerId)print(meta_marker.index)print(meta_marker.msg)
Extracting Science Data
c699util has a get_scans() function, just like tmread.momascience:
#!/usr/bin/env python3import c699utilc_tmfile = c699util.get_tmfile(30410)scan_count = 0for scan in c699util.get_scans(c_tmfile):scan_count += 1print("Number of scans:", scan_count)
The usual packet type, marker filtering, start time, etc. filtering options are available.
Unlike tmread, c699util provides a wrapper around MOMA Data View's ScienceDataCache class:
#!/usr/bin/env python3import c699util# Not needed# c_tmfile = c699util.construct_tmfile(tmfile.filename)# Notice that this factory function takes the absolute filename, just like# construct_tmfile# science_cache = c699util.construct_science_data_cache('/Users/mpallone/momadata/fm/2016-01-15-14.06.47-30410-MSFUNC/tm.mom.m3.s3')science_cache = c699util.get_science_data_cache(30410)
c699util.get_science_data_cache() is analagous to c699util.get_tmfile(), so it can be passed no arguments if the programmer wants to search the cwd, or just the TID to search for, or the absolute path of the tm.mom file, etc.
The science cache can be iterated through to get scan objects (just
like
c699util.get_scans()), or it can be indexed, as demonstrated below.
#!/usr/bin/env python3import c699utilscience_cache = c699util.get_science_data_cache(30410)last_scan = science_cache[-1]print("Last scan data:")print("Unix timestamp, in seconds:", last_scan.unix_timestamp())# Unix timestamp, in seconds: 1452890221.7956727print("Relative timestamp, in seconds:", last_scan.relative_timestamp())# Relative timestamp, in seconds: 5343.399699926376print("marker ID:", last_scan.marker_id())# marker ID: 2050print("marker Index:", last_scan.xina_marker_index())# marker Index: 136print("marker text:", last_scan.marker_text())# marker text: SCN 602 START Emission Current Source Blist_of_ion_counts = last_scan.counts()print("total ion count:", sum(list_of_ion_counts))print("total ion count:", last_scan.total_ion_count())# total ion count: 40463print("Highest count in the last_scan:", last_scan.highest_count())# Highest count in the last_scan: 708print("Bin number containing the highest count:", last_scan.highest_count_bin_num())# Bin number containing the highest count: 1710print("Lowest count:", last_scan.lowest_count())# Lowest count: 0# There should be one entry for every 100 binsrf_status_entry_list = last_scan.rf_status_entries()rf_entry = rf_status_entry_list[0]print("First RF Entry start bin:", rf_entry.start_bin)# First RF Entry start bin: 0print("First RF Entry RF Amp V:", rf_entry.rf_amp_v)# First RF Entry RF Amp V: 66.67613871395588print("First RF Entry RF Amp DAC V:", rf_entry.rf_amp_dac_v)# First RF Entry RF Amp DAC V: 70.00512770935893print("First RF Entry Aux Amp DAC V:", rf_entry.aux_amp_dac_v)# First RF Entry Aux Amp DAC V: 1.0998702980577946print("RF Amp Start:", last_scan.rf_amp_start())# RF Amp Start: 66.67613871395588print("RF Amp End:", last_scan.rf_amp_end())# RF Amp End: 993.6579284607433print("RF Amp DAC Start:", last_scan.rf_amp_dac_start())# RF Amp DAC Start: 70.00512770935893print("RF Amp DAC End:", last_scan.rf_amp_dac_end())# RF Amp DAC End: 996.3826513544906print("Aux Amp DAC Start:", last_scan.aux_amp_dac_start())# Aux Amp DAC Start: 1.0998702980577946print("Total scan time, in seconds:", last_scan.total_scan_time())# Total scan time, in seconds: 0.05000000074505805print("Peak counts per second:", last_scan.peak_counts_per_sec())# Peak counts per second: 70799998.9449978print("Pkt source type (26 or 27):", last_scan.src_pkt_type())# Pkt source type (26 or 27): 27print("Number of scans that went into this scan (typically 10 for sum packets):")print(last_scan.num_scans())# Number of scans that went into this scan (typically 10 for sum packets):# 10print("Does this scan have a scan status packet?", last_scan.has_scan_status())# Does this scan have a scan status packet? Trueprint("Number of scan status packets:", last_scan.num_scan_status_pkts())# Number of scan status packets: 10print("Does this scan have a preceding SEB HK packet?", last_scan.has_seb_hk_pkt())# Does this scan have a preceding SEB HK packet? Trueprint("Is this scan a dark count scan?", last_scan.is_dark_count_scan())# Is this scan a dark count scan? Falseprint("Sum of the ion counts for bins 500-600:")print(last_scan.selected_ion_count_sum_by_bin(500,600))# Sum of the ion counts for bins 500-600:# 3981print("Sum of the ion counts between masses 138-140:")print(last_scan.selected_ion_count_sum_by_mass(138,140))# Sum of the ion counts between masses 138-140:# 78print("Maximum ion count between bins 500-600:")print(last_scan.selected_ion_count_max_by_bin(500,600))# Maximum ion count between bins 500-600:# 537print("Maximum ion count between masses 138-140:")print(last_scan.selected_ion_count_max_by_mass(138,140))# Maximum ion count between masses 138-140:# 21print("seb_bin_time_readback:", last_scan.seb_bin_time_readback())# seb_bin_time_readback: 10.000000149011612print("seb_bin_time_readback_in_seconds:", last_scan.seb_bin_time_readback_in_seconds())# seb_bin_time_readback_in_seconds: 1.0000000149011612e-05print("seb_special_scan_id:", last_scan.seb_special_scan_id())# seb_special_scan_id: 602print("seb_raw_scan_value:", last_scan.seb_raw_scan_value())# seb_raw_scan_value: 127print("seb_scan_value:", last_scan.seb_scan_value())# seb_scan_value: 49.80392238497734print("seb_rf_freq_hz:", last_scan.seb_rf_freq_hz())# seb_rf_freq_hz: 988400.0print("seb_last_rf_amp_mon:", last_scan.seb_last_rf_amp_mon())# seb_last_rf_amp_mon: 993.6579284607433print("seb_rf_amp_dac_set:", last_scan.seb_rf_amp_dac_set())# seb_rf_amp_dac_set: 996.3826513544906print("seb_aux_amp_dac_set:", last_scan.seb_aux_amp_dac_set())# seb_aux_amp_dac_set: 7.297474631876097print("seb_counter_sel:", last_scan.seb_counter_sel())# seb_counter_sel: 1print("seb_bin_count_set:", last_scan.seb_bin_count_set())# seb_bin_count_set: 5000print("seb_bin_count_reg:", last_scan.seb_bin_count_reg())# seb_bin_count_reg: 20000print("seb_phase_cycle_rdbk:", last_scan.seb_phase_cycle_rdbk())# seb_phase_cycle_rdbk: 3print("seb_rf_step_set:", last_scan.seb_rf_step_set())# seb_rf_step_set: 0.1870379802200142print("seb_rf_step_reg:", last_scan.seb_rf_step_reg())# seb_rf_step_reg: -0.038366765173336245print("seb_aux_step_set:", last_scan.seb_aux_step_set())# seb_aux_step_set: 0.0012397955291065842print("seb_aux_step_reg:", last_scan.seb_aux_step_reg())# seb_aux_step_reg: 0.0006103608758678569print("seb_ionization_time_in_milliseconds:", last_scan.seb_ionization_time_in_milliseconds())# seb_ionization_time_in_milliseconds: 4.999999888241291print("seb_scan_em1:", last_scan.seb_scan_em1())# seb_scan_em1: -2069.6365661583154print("seb_scan_em1_raw:", last_scan.seb_scan_em1_raw())# seb_scan_em1_raw: 197print("seb_scan_em2:", last_scan.seb_scan_em2())# seb_scan_em2: 994.4167251074475print("seb_scan_em2_raw:", last_scan.seb_scan_em2_raw())# seb_scan_em2_raw: 0print("seb_src_a_foc_a_dac_set:", last_scan.seb_src_a_foc_a_dac_set())# seb_src_a_foc_a_dac_set: -39.6078431372549print("seb_src_b_foc_a_dac_set:", last_scan.seb_src_b_foc_a_dac_set())# seb_src_b_foc_a_dac_set: -39.6078431372549print("seb_src_a_foc_a_dac_reg:", last_scan.seb_src_a_foc_a_dac_reg())# seb_src_a_foc_a_dac_reg: -67.45098039215686print("seb_src_b_foc_a_dac_reg:", last_scan.seb_src_b_foc_a_dac_reg())# seb_src_b_foc_a_dac_reg: -67.45098039215686print("meta markers:", last_scan.get_meta_markers())# output omitted due to laziness, it's the same interface that's documented in the TMFile and TMPacket sectionsprint("m/z values:", last_scan.m_over_z_values())# (long tuple of doubles)print("list of TICs:", last_scan.total_ion_counts())# list of TICs: (3680, 3882, 4092, 4100, 4147, 4119, 4103, 4021, 4214, 4105)print("cTIC:", last_scan.corrected_total_ion_count())# cTIC: 1715842print("cTIC Factor:", last_scan.corrected_total_ion_count_factor())# cTIC Factor: 42.40522135001076print("cTIC Factors:", last_scan.corrected_total_ion_count_factors())# cTIC Factors: ()print("Packet version:", last_scan.science_data_pkt_version())# Packet version: 1print("seb_is_fil_a_on:", last_scan.seb_is_fil_a_on())# seb_is_fil_a_on: Falseprint("seb_is_fil_b_on:", last_scan.seb_is_fil_b_on())# seb_is_fil_b_on: Trueprint("Scan mode:", last_scan.scan_mode_as_string())# Scan mode: EIprint("SEB sequence packet indexes:", last_scan.seb_sequence_pkt_indexes())# SEB sequence packet indexes: (68463, 68464, 68465)print("EM on times (ms):", last_scan.em_on_times_in_ms())# EM on times (ms): (600.1000052131712, 0.0)
Interface Differences Between tmread and c699util
This section is intended for those who have used tmread on SAM, LADEE, or MAVEN. My hope is that such users can use c699util just as they use tmread, using this section as a cheatsheet as needed.
#!/usr/bin/env python3import tmread, c699utiltmfile = tmread.get_tmfile(30410) # Give it a TID and let it find the file for usc_tmfile = c699util.construct_tmfile(tmfile.filename)AUX_AMP_DAC_SET_HKID = 61RF_AMP_MON_HKID = 62#------------------------------------------------------------------------------# TMFile interface differences#------------------------------------------------------------------------------# Getting a TMFile:tmfile = tmread.get_tmfile(30410) # Can be passed TID or absolute filenamec_tmfile = c699util.construct_tmfile(tmfile.filename) # requires absolute filenamefilename = tmfile.filenamefilename = c_tmfile.filename()dir_string = tmfile.directory_stringdir_string = c_tmfile.directory_string()t0_in_unix_time = tmfile.start_time().unix # Returns TMTimestamp objectt0_in_unix_time = c_tmfile.t0_in_unix_time() # Returns a floatmsg_log = tmfile.message_logmsg_log = c_tmfile.message_log()#------------------------------------------------------------------------------# TMPacket interface differences#------------------------------------------------------------------------------pkt = tmfile[-1]c_pkt = c_tmfile[-1]# Packet type with GSE bit masked out:pkt_type = pkt.typepkt_type = c_pkt.get_type()# Full packet type:full_pkt_type = pkt.full_typefull_pkt_type = c_pkt.full_type()total_length = pkt.total_lengthtotal_length = c_pkt.total_length()# Doesn't included the 8 byte header and 4 byte checksum, unlike total_lengthdata_length = pkt.lengthdata_length = c_pkt.length()checksum = pkt.checksumchecksum = c_pkt.checksum()gse_created = pkt.gse_createdgse_created = c_pkt.gse_created()sequence_number = pkt.sequencesequence_number = c_pkt.sequence()fsw_timestamp = pkt.raw_timefsw_timestamp = c_pkt.sclk()unix_timestamp = pkt.timestamp.unix # TMTimestamp objectunix_timestamp = c_pkt.unix_timestamp() # floatrelative_timestamp = pkt.timestamp.relative # TMTimestamp objectrelative_timestamp = c_pkt.relative_timestamp() # floatmarker_text = pkt.marker_textmarker_text = c_pkt.marker_text()marker_id = pkt.mkidmarker_id = c_pkt.marker_id()msg = pkt.messagemsg = c_pkt.message()## Housekeeping data interface:#data_dict = tmread.extract_tmfields(tmfile, [800])hkid_800_datapoints = data_dict[800]first_datapoint = hkid_800_datapoints[0]timestamp = first_datapoint.tsvalue = first_datapoint.valdata_dict = tmread.extract_tmfields(c_tmfile, [800])hkid_800_datapoints = data_dict[800]first_datapoint = hkid_800_datapoints[0]unix_timestamp = first_datapoint.unix_timestamprelative_timestamp = first_datapoint.relative_timestampvalue = first_datapoint.value#------------------------------------------------------------------------------# Scan interface differences#------------------------------------------------------------------------------scan = list(tmread.get_scans(tmfile))[-1]c_scan = list(c699util.get_scans(c_tmfile))[-1]result = scan.timestamp.unix # Returns a TMTimestamp objectresult = c_scan.unix_timestamp(); # Returns a floatresult = scan.timestamp.relative # Returns a TMTimestamp objectresult = c_scan.relative_timestamp(); # Returns a floatresult = scan.marker_textresult = c_scan.marker_text();result = scan.scanpoints # list of MomaScanPoint objectsresult = c_scan.counts(); # list of integersresult = scan.total_ion_countresult = c_scan.total_ion_count();result = scan.highest_countresult = c_scan.highest_count();result = scan.highest_count_bin_numresult = c_scan.highest_count_bin_num();result = scan.rf_amp_startresult = c_scan.rf_amp_start();result = scan.rf_amp_endresult = c_scan.rf_amp_end();result = scan.rf_amp_dac_startresult = c_scan.rf_amp_dac_start();result = scan.rf_amp_dac_endresult = c_scan.rf_amp_dac_end();result = scan.aux_amp_dac_startresult = c_scan.aux_amp_dac_start();result = scan.aux_amp_dac_endresult = c_scan.aux_amp_dac_end();result = scan.total_scan_timeresult = c_scan.total_scan_time();result = scan.peak_counts_per_secresult = c_scan.peak_counts_per_sec();result = scan.src_pkt_typeresult = c_scan.src_pkt_type();result = scan.num_scansresult = c_scan.num_scans();result = bool(scan.seb_state.num_scan_status_pkt_updates)result = c_scan.has_scan_status();result = scan.seb_state.num_scan_status_pkt_updatesresult = c_scan.num_scan_status_pkts();result = scan.seb_state.scan_bin_time_readbackresult = c_scan.seb_bin_time_readback()result = scan.seb_state.scan_bin_time_readback_in_secondsresult = c_scan.seb_bin_time_readback_in_seconds()result = scan.seb_state.special_scan_idresult = c_scan.seb_special_scan_id()result = scan.seb_state.raw_scan_valueresult = c_scan.seb_raw_scan_value()result = scan.seb_state.scan_valueresult = c_scan.seb_scan_value()result = scan.seb_state.rf_freqresult = c_scan.seb_rf_freq_hz()result = scan.seb_state.last_rf_amp_monresult = c_scan.seb_last_rf_amp_mon()result = scan.seb_state.rf_amp_dac_setresult = c_scan.seb_rf_amp_dac_set()result = scan.seb_state.aux_amp_dac_setresult = c_scan.seb_aux_amp_dac_set()result = scan.seb_state.counter_selresult = c_scan.seb_counter_sel()result = scan.seb_state.bin_count_setresult = c_scan.seb_bin_count_set()result = scan.seb_state.bin_count_regresult = c_scan.seb_bin_count_reg()result = scan.seb_state.phase_cycle_rdbkresult = c_scan.seb_phase_cycle_rdbk()result = scan.seb_state.rf_step_setresult = c_scan.seb_rf_step_set()result = scan.seb_state.rf_step_regresult = c_scan.seb_rf_step_reg()result = scan.seb_state.rf_step_regresult = c_scan.seb_aux_step_set()result = scan.seb_state.aux_step_regresult = c_scan.seb_aux_step_reg()result = scan.seb_state.ionization_timeresult = c_scan.seb_ionization_time_in_milliseconds()result = scan.seb_state.scan_em1result = c_scan.seb_scan_em1()result = scan.seb_state.scan_em2result = c_scan.seb_scan_em2()result = scan.seb_state.srcA_foc_a_dac_setresult = c_scan.seb_src_a_foc_a_dac_set()result = scan.seb_state.srcB_foc_a_dac_setresult = c_scan.seb_src_b_foc_a_dac_set()result = scan.seb_state.srcA_foc_a_dac_regresult = c_scan.seb_src_a_foc_a_dac_reg()result = scan.seb_state.srcB_foc_a_dac_regresult = c_scan.seb_src_b_foc_a_dac_reg()result = bool(scan.seb_state.num_hk_pkt_updates)result = c_scan.has_seb_hk_pkt();result = scan.seb_state.is_emon_aresult = c_scan.seb_is_emon_a();result = scan.seb_state.is_emon_bresult = c_scan.seb_is_emon_b();result = scan.count_ions(min_bin=min_bin, max_bin=max_bin)result = c_scan.selected_ion_count_sum_by_bin(min_bin, max_bin);result = scan.count_ions(min_mass=min_mass, max_mass=max_mass)result = c_scan.selected_ion_count_sum_by_mass(min_mass, max_mass);result = scan.max_ion_count(min_bin=min_bin, max_bin=max_bin)result = c_scan.selected_ion_count_max_by_bin(min_bin, max_bin);result = scan.max_ion_count(min_mass=min_mass, max_mass=max_mass)result = c_scan.selected_ion_count_max_by_mass(min_mass, max_mass);
c699util and the 699 Gnuplot module
If you use GnuplotArgumentParser (a class defined in 699util), be sure
to pass use_c699util=True to the constructor, so that it will use
c699util objects internally. (This is not default behavior because I
don't want to break older Python scripts.)