Giter Club home page Giter Club logo

pylinac's Introduction

https://storage.googleapis.com/pylinac_demo_files/Pylinac-GREEN.png Latest Version

PyPI - Python Version

PyPI - Wheel

MIT Read the Docs (version)

PyPI - Downloads

GitHub commit activity (branch)

JOSS Paper

Pylinac provides TG-142 quality assurance (QA) tools to Python programmers in the field of therapy and diagnostic medical physics.

Pylinac contains high-level modules for automatically analyzing images and data generated by linear accelerators, CT simulators, and other radiation oncology equipment. Most scripts can be utilized with less than 10 lines of code.

The library also contains lower-level modules & tools for creating your own image analysis algorithms.

The major attributes of the package are:

  • Simple, concise image analysis API
  • Automatic analysis of imaging and performance metrics like MTF, Contrast, ROIs, etc.
  • PDF report generation for solid documentation
  • Automatic phantom registration even if you don't set up your phantom perfect
  • Image loading from file, ZIP archives, or URLs

Install via pip:

$ pip install pylinac

See the Installation page for further details.

You may cite the pylinac library in publications; see the paper in the Journal of Open Source Software. The citation string is:

Kerns, J. R., (2023). Pylinac: Image analysis for routine quality assurance in radiotherapy. Journal of Open Source Software, 8(92), 6001, https://doi.org/10.21105/joss.06001

And the BibTeX entry:

@article{Kerns2023, doi = {10.21105/joss.06001}, url = {https://doi.org/10.21105/joss.06001}, year = {2023}, publisher = {The Open Journal}, volume = {8}, number = {92}, pages = {6001}, author = {James R. Kerns}, title = {Pylinac: Image analysis for routine quality assurance in radiotherapy}, journal = {Journal of Open Source Software} }

I was also interviewed due to this article! Thanks to Arfon and Abby for the fun interview: YouTube.

To get started, install the package, run the demos, view the API docs, and learn the module design, visit the Full Documentation on Read The Docs.

Load DICOM files, XIM, and TIFF images:

from pylinac import image
from pylinac.core.image import XIM

my_dcm = image.load("path/to/my/image.dcm")
my_dcm.metadata.GantryAngle  # the GantryAngle tag of the DICOM file
# these won't have the metadata property as they aren't DICOM
my_tiff = image.load("path/to/my/image.tiff")
my_jpg = image.load("path/to/my/image.jpg")

my_xim_file = r"C:\TDS\H12345\QA\image.xim"
xim_img = XIM(my_xim_file)

# plot the image
xim_img.plot()

# see the XIM properties
print(xim_img.properties)

Read more about DICOM and pixel loading: Image Loading. Read more about XIM images: XIM Images.

Images can be manipulated in a variety of ways. This is helpful when combined with the loading utilities above:

from pylinac import image

# load an image
my_img = image.load("path/to/my/image.dcm")

# rotate the image
my_img.rotate(90)

# flip the image
my_img.flipud()

# crop the image
my_img.crop(pixels=50, edges=("left", "top"))

# invert the image
my_img.bit_invert()

# normalize the array (max value = 1)
my_img.normalize()

# plot the image
my_img.plot()

# save the image back out to DICOM
my_img.save("path/to/new.dcm")

Convert TIFF to DICOM:

from pylinac import image

# load the TIFF image
new_dicom = image.tiff_to_dicom(
    "path/to/my/image.tiff", sid=1000, gantry=90, coll=0, couch=0, dpi=400
)

# save out the FILE to DICOM
new_dicom.save("path/to/new.dcm")

Compute gamma between two arrays:

from pylinac import image

# load the images
img1 = image.load("path/to/image1.dcm")
img2 = image.load("path/to/image2.dcm")

# compute gamma
gamma = image.gamma_2d(
    reference=img1.array,
    evaluation=img2.array,
    dose_to_agreement=1,
    distance_to_agreement=1,
    gamma_cap_value=2,
    global_dose=True,
    dose_threshold=5,
)

# plot the gamma map
plt.imshow(gamma)

Compute gamma for 1D profiles:

from pylinac import profile

# load the images and profiles
img1 = image.load("path/to/image1.dcm")
img2 = image.load("path/to/image2.dcm")
mid_img1_profile = img1.array[img1.shape[0] // 2, :]
mid_img2_profile = img2.array[img2.shape[0] // 2, :]

# compute gamma
gamma = profile.gamma_1d(
    reference=mid_img1_profile,
    evaluation=mid_img2_profile,
    dose_to_agreement=1,
    distance_to_agreement=1,
    gamma_cap_value=2,
    global_dose=True,
    dose_threshold=5,
)

# plot the gamma map
plt.plot(gamma)

Pylinac comes with several built-in metrics that can be computed on 1D profiles, each of which can be configured.

Writing new metrics is also easy.

Calculate the penumbra of a profile using the built-in LeftPenumbraMetric:

from pylinac import profile
from pylinac.metrics.profile import LeftPenumbraMetric

# load the image and profile
img = image.load("path/to/image.dcm")
mid_profile = FWXMProfile(img.array[img.shape[0] // 2, :])

# compute the penumbra
left_penumbra = mid_profile.compute(metrics=[LeftPenumbraMetric(upper=80, lower=20)])

print(left_penumbra)  # prints the penumbra value

Read more about 1D metrics: Profiles & 1D Metrics.

Convert gantry, collimator, and couch coordinates to and from each other:

from pylinac.core.scale import convert, MachineScale

gantry = 0
coll = 90
couch = 45

new_gantry, new_coll, new_couch = convert(
    input_scale=MachineScale.Varian,
    output_scale=MachineScale.IEC61217,
    gantry=gantry,
    collimator=coll,
    rotation=couch,
)

Read more: Coordinate Systems.

Want to generate images to test out your image analysis algorithms? Pylinac can do that.

Generate an AS1000 50x50mm, centered open field image at gantry 45:

from matplotlib import pyplot as plt

from pylinac.core.image_generator import AS1000Image
from pylinac.core.image_generator.layers import FilteredFieldLayer, GaussianFilterLayer

as1000 = AS1000Image()  # this will set the pixel size and shape automatically
as1000.add_layer(
    FilteredFieldLayer(field_size_mm=(50, 50))
)  # create a 50x50mm square field
as1000.add_layer(
    GaussianFilterLayer(sigma_mm=2)
)  # add an image-wide gaussian to simulate penumbra/scatter
as1000.generate_dicom(
    file_out_name="my_AS1000.dcm", gantry_angle=45
)  # create a DICOM file with the simulated image
# plot the generated image
plt.imshow(as1000.image)

Read More: Image Generator.

TG-51 & TRS-398 Absolute Dose Calibration - Input the raw data and pylinac can calculate either individual values (kQ, PDDx, Pion, etc) or use the provided classes to input all measurement data and have it calculate all factors and dose values automatically.

Example script:

from pylinac import tg51, trs398

ENERGY = 6
TEMP = 22.1
PRESS = tg51.mmHg2kPa(755.0)
CHAMBER = "30013"  # PTW
P_ELEC = 1.000
ND_w = 5.443  # Gy/nC
MU = 200
CLINICAL_PDD = 66.5

tg51_6x = tg51.TG51Photon(
    unit="TrueBeam1",
    chamber=CHAMBER,
    temp=TEMP,
    press=PRESS,
    n_dw=ND_w,
    p_elec=P_ELEC,
    measured_pdd10=66.4,
    lead_foil=None,
    clinical_pdd10=66.5,
    energy=ENERGY,
    voltage_reference=-300,
    voltage_reduced=-150,
    m_reference=(25.65, 25.66, 25.65),
    m_opposite=(25.64, 25.65, 25.65),
    m_reduced=(25.64, 25.63, 25.63),
    mu=MU,
    tissue_correction=1.0,
)

# Done!
print(tg51_6x.dose_mu_dmax)

# examine other parameters
print(tg51_6x.pddx)
print(tg51_6x.kq)
print(tg51_6x.p_ion)

# change readings if you adjust output
tg51_6x.m_reference_adjusted = (25.44, 25.44, 25.43)
# print new dose value
print(tg51_6x.dose_mu_dmax_adjusted)

# generate a PDF for record-keeping
tg51_6x.publish_pdf(
    "TB1 6MV TG-51.pdf",
    notes=["My notes", "I used Pylinac to do this; so easy!"],
    open_file=False,
)

# TRS-398 is very similar and just as easy!

Planar Phantom Analysis (Leeds TOR, StandardImaging QC-3 & QC-kV, Las Vegas, Doselab MC2 (kV & MV), SNC kV & MV, PTW EPID QC) - Features:

  • Automatic phantom localization - Set up your phantom any way you like; automatic positioning, angle, and inversion correction mean you can set up how you like, nor will setup variations give you headache.
  • High and low contrast determination - Analyze both low and high contrast ROIs. Set thresholds as you see fit.

Example script:

from pylinac import LeedsTOR, StandardImagingQC3, LasVegas, DoselabMC2kV, DoselabMC2MV

leeds = LeedsTOR("my_leeds.dcm")
leeds.analyze()
leeds.plot_analyzed_image()
leeds.publish_pdf()

qc3 = StandardImagingQC3("my_qc3.dcm")
qc3.analyze()
qc3.plot_analyzed_image()
qc3.publish_pdf("qc3.pdf")

lv = LasVegas("my_lv.dcm")
lv.analyze()
lv.plot_analyzed_image()
lv.publish_pdf("lv.pdf", open_file=True)  # open the PDF after publishing

...

Winston-Lutz Analysis - The Winston-Lutz module analyzes EPID images taken of a small radiation field and BB to determine the 2D distance from BB to field CAX. Additionally, the isocenter size of the gantry, collimator, and couch can all be determined without the BB being at isocenter. Analysis is based on Winkler et al , Du et al, and Low et al.

Features:

  • Couch shift instructions - After running a WL test, get immediate feedback on how to shift the couch. Couch values can also be passed in and the new couch values will be presented so you don't have to do that pesky conversion. "Do I subtract that number or add it?"
  • Automatic field & BB positioning - When an image or directory is loaded, the field CAX and the BB are automatically found, along with the vector and scalar distance between them.
  • Isocenter size determination - Using backprojections of the EPID images, the 3D gantry isocenter size and position can be determined independent of the BB position. Additionally, the 2D planar isocenter size of the collimator and couch can also be determined.
  • Image plotting - WL images can be plotted separately or together, each of which shows the field CAX, BB and scalar distance from BB to CAX.
  • Axis deviation plots - Plot the variation of the gantry, collimator, couch, and EPID in each plane as well as RMS variation.
  • File name interpretation - Rename DICOM filenames to include axis information for linacs that don't include such information in the DICOM tags. E.g. "myWL_gantry45_coll0_couch315.dcm".

Example script:

from pylinac import WinstonLutz

wl = WinstonLutz("wl/image/directory")  # images are analyzed upon loading
wl.plot_summary()
print(wl.results())
wl.publish_pdf("my_wl.pdf")

Starshot Analysis - The Starshot module analyses a starshot image made of radiation spokes, whether gantry, collimator, MLC or couch. It is based on ideas from Depuydt et al and Gonzalez et al.

Features:

  • Analyze scanned film images, single EPID images, or a set of EPID images - Any image that you can load in can be analyzed, including 1 or a set of EPID DICOM images and films that have been digitally scanned.
  • Any image size - Have machines with different EPIDs? Scanned your film at different resolutions? No problem.
  • Dose/OD can be inverted - Whether your device/image views dose as an increase in value or a decrease, pylinac will detect it and invert if necessary.
  • Automatic noise detection & correction - Sometimes there's dirt on the scanned film; sometimes there's a dead pixel on the EPID. Pylinac will detect these spurious noise signals and can avoid or account for them.
  • Accurate, FWHM star line detection - Pylinac uses not simply the maximum value to find the center of a star line, but analyzes the entire star profile to determine the center of the FWHM, ensuring small noise or maximum value bias is avoided.
  • Adaptive searching - If you passed pylinac a set of parameters and a good result wasn't found, pylinac can recover and do an adaptive search by adjusting parameters to find a "reasonable" wobble.

Example script:

from pylinac import Starshot

star = Starshot("mystarshot.tif")
star.analyze(radius=0.75, tolerance=1.0, fwhm=True)
print(star.results())  # prints out wobble information
star.plot_analyzed_image()  # shows a matplotlib figure
star.publish_pdf()  # publish a PDF report

VMAT QA - The VMAT module consists of two classes: DRGS and DRMLC, which are capable of loading an EPID DICOM Open field image and MLC field image and analyzing the images according to the Varian RapidArc QA tests and procedures, specifically the Dose-Rate & Gantry-Speed (DRGS) and MLC speed (MLCS) tests.

Features:

  • Do both tests - Pylinac can handle either DRGS or DRMLC tests.
  • Adjust for offsets - Older VMAT patterns were off-center. Pylinac will find the field regardless.

Example script:

from pylinac import DRGS, DRMLC

drgs = DRGS(image_paths=["path/to/DRGSopen.dcm", "path/to/DRGSdmlc.dcm"])
drgs.analyze(tolerance=1.5)
print(drgs.results())  # prints out ROI information
drgs.plot_analyzed_image()  # shows a matplotlib figure
drgs.publish_pdf("mydrgs.pdf")  # generate a PDF report

CatPhan, Quart, ACR phantom QA - The CBCT module automatically analyzes DICOM images of a CatPhan 504, 503, 600, 604, Quart DVT, and ACR CT/MR acquired when doing CT, CBCT, or MR quality assurance. It can load a folder or zip file that the images are in and automatically correct for phantom setup in 6 axes. CatPhans analyze the HU regions and image scaling (CTP404), the high-contrast line pairs (CTP528) to calculate the modulation transfer function (MTF), and the HU uniformity (CTP486) on the corresponding slice. Quart and ACR analyze similar metrics where possible.

Features:

  • Automatic phantom registration - Your phantom can be tilted, rotated, or translated--pylinac will register the phantom.
  • Automatic testing of all major modules - Major modules are automatically registered and analyzed.
  • Any scan protocol - Scan your CatPhan with any protocol; or even scan it in a regular CT scanner. Any field size or field extent is allowed.
  • Customize modules - You can easily override settings in the event you have a custom scenario such as a partial scan.

Example script:

from pylinac import (
    CatPhan504,
    CatPhan503,
    CatPhan600,
    CatPhan604,
    QuartDVT,
    ACRCT,
    ACRMRILarge,
)

# for this example, we'll use the CatPhan504
cbct = CatPhan504("my/cbct_image_folder")
cbct.analyze(
    hu_tolerance=40,
    scaling_tolerance=1,
    thickness_tolerance=0.2,
    low_contrast_threshold=1,
)
print(cbct.results())
cbct.plot_analyzed_image()
cbct.publish_pdf("mycbct.pdf")

Log Analysis - The log analyzer module reads and parses Varian linear accelerator machine logs, both Dynalogs and Trajectory logs. The module also calculates actual and expected fluences as well as performing gamma evaluations. Data is structured to be easily accessible and easily plottable.

Unlike most other modules of pylinac, the log analyzer module has no end goal. Data is parsed from the logs, but what is done with that info, and which info is analyzed is up to the user.

Features:

  • Analyze Dynalogs or Trajectory logs - Either platform is supported. Tlog versions 2.1 and 3.0 supported.
  • Save Trajectory log data to CSV - The Trajectory log binary data format does not allow for easy export of data. Pylinac lets you do that so you can use Excel or other software that you use with Dynalogs.
  • Plot or analyze any axis - Every data axis can be plotted: the actual, expected, and even the difference.
  • View actual or expected fluences & calculate gamma - View fluences and gamma maps for any log.
  • Anonymization - Anonymize your logs so you can share them with others.

Example script:

from pylinac import load_log

tlog = load_log("tlog.bin")
# after loading, explore any Axis of the Varian structure
tlog.axis_data.gantry.plot_actual()  # plot the gantry position throughout treatment
tlog.fluence.gamma.calc_map(doseTA=1, distTA=1, threshold=10, resolution=0.1)
tlog.fluence.gamma.plot_map()  # show the gamma map as a matplotlib figure
tlog.publish_pdf()  # publish a PDF report

dlog = load_log("dynalog.dlg")
...

Picket Fence MLC Analysis - The picket fence module is meant for analyzing EPID images where a "picket fence" MLC pattern has been made. Physicists regularly check MLC positioning through this test. This test can be done using film and one can "eyeball" it, but this is the 21st century and we have numerous ways of quantifying such data. This module attains to be one of them. It will load in an EPID dicom image and determine the MLC peaks, error of each MLC pair to the picket, and give a few visual indicators for passing/warning/failing.

Features:

  • Preset & customizable MLC configurations - Standard configurations are built-in and you can create your own configuration of leaves if needed.
  • Easy-to-read pass/warn/fail overlay - Analysis gives you easy-to-read tools for determining the status of an MLC pair.
  • Any Source-to-Image distance - Whatever your clinic uses as the SID for picket fence, pylinac can account for it.
  • Account for panel translation - Have an off-CAX setup? No problem. Translate your EPID and pylinac knows.
  • Account for panel sag - If your EPID sags at certain angles, just tell pylinac and the results will be shifted.

Example script:

from pylinac import PicketFence

pf = PicketFence("mypf.dcm")
pf.analyze(tolerance=0.5, action_tolerance=0.25)
print(pf.results())
pf.plot_analyzed_image()
pf.publish_pdf()

Open Field Analysis - Field analysis from a digital image such as EPID DICOM or 2D device array can easily be analyzed. The module contains built-in flatness and symmetry equation definitions but is extensible to quickly create custom F&S equations.

Features: * EPID or device data - Any EPID image or the SNC Profiler. * Built-in F&S equations - The common Elekta, Varian, and Siemens definitions are included * Extensible equations - Adding custom equations for image metrics are easy

Example script:

from pylinac import FieldAnalysis, DeviceFieldAnalysis, Protocol

fa = FieldAnalysis(path="myFS.dcm")  # equivalently, DeviceFieldAnalysis
fa.analyze(protocol=Protocol.VARIAN)
# print results
print(fa.results())
# get results as a dict
fa.results_data()
# plot results
fa.plot_analyzed_image()
# publish a PDF file
fa.publish_pdf(filename="my field analysis.pdf")

Have questions? Ask them on the pylinac discourse server.

Contributions to pylinac can be many. The most useful things a non-programmer can contribute are images to analyze and bug reports. If you have VMAT images, starshot images, machine log files, CBCT DICOM files, or anything else you want analyzed, upload them privately here.

See the full Contributing page for more details.

pylinac's People

Contributors

alanphys avatar anmcgrath avatar bastula avatar ckswilliams avatar crcrewso avatar ethanio12345 avatar gdrosos avatar gitter-badger avatar jmadamesila avatar jmartens avatar jrkerns avatar keithoffer avatar luisolivaresj avatar mchamberland avatar midamo avatar quantifiedcode-bot avatar randlet avatar safirzouzout avatar stephenterry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pylinac's Issues

PicketFence does not detect pickets for small patterns

Pickets are derived from a median profile along each image axis, but if the picket fence pattern itself is smaller than half the image (e.g. a large SSD) then the median will be zero and not detect the pickets. Behavior should take the maximum instead.

Add matplotlib directives to docs

ReadTheDocs currently does not have matplotlib for the Python 3 build interpreter, and a pip install fails, thus, the matplotlib directive can't be used. When RTD gets matplotlib for py3, then the directives can be used. Until then, pictures will have to suffice.

Account for partially-covered leaves in log analyzer

As of now, the behavior is to calculate the leaf fluence as one pixel, which does not allow for partially-covered leaves. This may (slightly) affect the gamma score. One solution is to calculate the fluence more realistically in the y-direction. The pixels would simply be mapped to the realistic leaf width.

Starshot: Results are stochastic

Given that the minimum diameter is found using an evolutionary algorithm it is understandable that results can vary. Unfortunately, results can vary widely, creating an unnecessarily wide range of results. A more predictable minimization function should be used.

Log analyzer: number of beam holds may be faulty

The log analyzer currently looks for changes in the beam hold state by taking the diff of the beam hold state array and looking for differences of 1 (e.g. 0 -> 1, 1 -> 2). This does not catch trajectory log holds that go from 0 -> 2. Bug report here; thanks to Anthony for catching it.

pylinac installation issues

Hi,

I tried to install pylinac using pip on winpython as well as trying python setup.py install but I get the error message no pylinac module found. I have all your dependencies with the latest versions. I have python 2.7.6.

Starshots can fail if image has a pin prick

Oftentimes a physicists will add a mark or pin prick to the image to know the orientation of the image. These usually cause extreme values, and can cause analysis to fail because the image inversion goes the wrong way.

Add pylinac to binstar

conda is the pip for scientific python package management, and binstar seems to be the pypi of conda. Given that pylinac depends on scientific packages, it may be better in some cases to install pylinac via conda.

CBCT demo files occasionally trip

During testing when the CBCT demo files are quickly being unpacked/deleted, sometimes the test runner gets tripped up by the OS being too slow and can't load the demo files because an empty folder is left from the unpacked demo files.

Warn Python 2.x users

pylinac is installable in python 2, but will fail as it has certain py3-only components. pylinac should issue a warning if trying to use pylinac on py2, before an error raises that is not immediately apparent what's going on.

Leeds analysis failing

Several conditions are nullifying Leeds analysis. This is largely due to the uneven background of various images. kV imagers are performing very differently, as well as the various exposure protocols allowed.

Non-local filters and histogram equalization would help; unfortunately these are in the skimage libary and has not been incorporated into pylinac...yet.

Add wheels

Pylinac is currently an egg; support wheel as well.

Add batch processing for MachineLog

MachineLog currently only handles one file at a time. It should be trivial to add batch processing (e.g. a directory), at least for reading in. Batch processing of, say, fluence should be allowable, perhaps through a method.

Reading trajectory log's txt files with a blank line causes crash

There were sporadic problems with reading in the txt file before, but I think I've got a handle on it now. When a blank line is encountered (sometimes but not always the case) splitting the item in two crashes the process.

This can be fixed by checking the length of the line.

CBCT fails when ring artifact present

When a full ring artifact is present in a CBCT acquisition, the algorithm thinks the ring is the phantom edge, causing all radius-based calculations to fail.

Winston Lutz: BB occasionally mislabeled

The Winston Lutz analysis looks for the BB using a few conditions. Unfortunately, it would not discriminate between very small looking ROIs (noise) and the BB. A minimum size criteria should be added.

Starshot: wobble diameter isn't correct

Wobble diameter for the starshot is not correct, giving a wobble slightly smaller than what it should be. The point-to-line distance algorithm should be fixed.

Convert "Open File" dialog from PyQt4 to tkinter

Currently, pylinac uses PyQt4 for it's GUI (which is fine), but if a user only wants the API-level interface, it still uses PyQt4, almost exclusively for File Dialogs. This should be converted to something simpler and without a dependency, namely tkinter.

Add *.txt info to MachineLog if available

Trajectory log creation also (most of the time it seems) makes a *.txt file, which carries a few pieces of additional information like patient ID, plan name, and beam energy. If the txt file is in the same directory it should be incorporated into the MachineLog data

CBCT roll adjusted the wrong way

The CBCT module would account for roll of the phantom, but this is being applied the wrong way for the spatial resolution slice and HU linearity nodes.

Allow multiple images to be superimposed

Sometimes a physicist wants to combined multiple images to form one single image. E.g. a collimator star shot can be formed by taking single EPID images of one specific collimator angle. These single angle images can be superimposed to form a full collimator star shot. Other examples exist.

Add ability to load baseline to BeamImage for relative comparison (TG142-style)

TG-142 states that beam profiles (flatness & symmetry) should be analyzed against a baseline. Currently, the flatsym module only computes objective values. It would be advantageous to be able to load in a baseline image, e.g. taken at the time of commissioning/annual/repair, and the relative profile analyzed to see if it exceeds the 1%/2% relative change.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.