prosi3d.preprocessing package

Submodules

prosi3d.preprocessing.camera module

prosi3d.preprocessing.camera.Apply_corrections_to_image(forig, scale, imgpoints, imgpoints2, objpoints, fromfile='C:\\Users\\ringel\\Lokal\\Python\\Pixel-KOS\\img\\correction_cmos.h5', num_x=43)[source]

Apply_corrections_to_image(fpathorig, 4, 0, 0, 0, 1, 55) –> 55 Cornerpoints per axis (at the moment squared necessary), scaling 4 times of calibration data, calibration data from file Apply_corrections_to_image(fpathorig, 4, imgpoints, imgpoints2, objpoints, 0, 43) –> grid of 43 Cornerpoints and calibration data from entered directly

Apply calibration values for perspektive (unwarp) and distortion to another image

prosi3d.preprocessing.camera.Points_and_correction(img, fname, x=43, y=43)[source]

find and apply corrections using a chessboard grid image

prosi3d.preprocessing.camera.chessCorners(img, fname, x=43, y=43)[source]

First function to run. Finds chessboard corners if possible Args: img, fname, x=43, y=43 Returns: gray, objpoints, imgpoints

prosi3d.preprocessing.camera.eosCorners(path, n=43, lay=1)[source]

Find x,y values for corners of chessboard job. Read first layer file ‘eosprint_layer00001.h5’ and if not existant run readDf() and df2Layers_hdf() to create layer files from openjz.txt file. Calculate coordinates and save in file eoscorners.h5 Args: path to openjobfile, nominal number of cornes which can be found Returns: corner coordinates

prosi3d.preprocessing.camera.extrapolate_full_built_field(xtable, ytable, plattformsize=250)[source]
prosi3d.preprocessing.camera.findPixelByCoord(x, y, xtable, ytable, img, tol=0.05)[source]

Calculate pixel for machine coordinate do not use for generation of total time series by iteration - too slow Arguments: xtable, ytable (pixel and midpoint coordinate), x, y (coordinates), tol (tolerance for early filter for cpu saving; should at least equal pixel pitch) Returns: xpx, ypx

prosi3d.preprocessing.camera.findPixelByCoordFlip(xtable, ytable, img, x, y, tol=0.05)[source]

Calculate pixel for machine coordinate Arguments: xtable, ytable (pixel and midpoint coordinate), x, y (coordinates), tol (tolerance for early filter for cpu saving; should at least equal pixel pitch) Returns: xpx, ypx

prosi3d.preprocessing.camera.imgvalue(img, xpx, ypx)[source]
prosi3d.preprocessing.camera.loopFilesInFolder_imgCorr(path, corrfile='C:\\Users\\ringel\\Lokal\\Python\\Pixel-KOS\\img\\correction_cmos.h5', progress=True)[source]
prosi3d.preprocessing.camera.matchCorners(path, scale=4)[source]
prosi3d.preprocessing.camera.px_pitch_mcos()[source]

iterate all pixels and filter machine coordinate in xytime using pixel center point and pixel pitch

prosi3d.preprocessing.camera.refering_pixel_table(corners, chessfieldwidth=4, tol=0.5)[source]

Calculate correlation tables between corner points and machine coordinates Args: corners Returns: xtable, ytable

prosi3d.preprocessing.camera.resize_img(imgpath, scale=0.25, max_px=2500)[source]
prosi3d.preprocessing.camera.undistort(img, fname, objpoints, imgpoints, scale=1)[source]
prosi3d.preprocessing.camera.unwarpProj(img, fname, imgpoints, scale=1, num_x=43)[source]

prosi3d.preprocessing.debug module

prosi3d.preprocessing.debug.error_determination(df, pos_err, pos_io, error_treshold=0.2)[source]

REPLACED BY solver_error_determination() 07.02.2023

tries to find out what kind of error accured - which shift direction logic: - use df between pos_io and pos_err+20 - try to find out the shift around err_pos by matching_sequence -

errortype ==

0: shift is null, does not work 1: missing weld assumed between pos_io and true_pos_err 2: missing weld assumed between pos_io and pos_err 3: missing jump assumed between pos_io and true_pos_err 4: missing jump assumed between pos_io and pos_err 5: broken weld assumed between pos_io and pos_err -1: could not determine

Args: df, pos_err, error_treshold Returns: error_type, shift, pos_err

prosi3d.preprocessing.debug.solver_error_determination(df, pos_err, pos_io, error_treshold=0.2)[source]

true error is in between pos_io and pos_err in df

pos_err could be the true_error_position

missing weld not possible because pos_err is calculated for welds > 1 ms –> found position should be measured missing jump afterwards pos_err possible additional jump / split weld possible

pos_err could be afterwards true_error_position

missing weld possible –> shift < 0 missing jump possible –> shift < 0 additional jump possible –> shift > 0

multiple error types could counterbalance shift most errors are missing welds

1 ) function tries to find out the shift in the area of err_pos

using matching sequence and matching unique using unique candidates in dura_ttl for the dura_eos value at error position

shift is typically 1 or 2 and < 5

2 ) shift == 0: shift calculation went wrong, counterbalancing errors or sth else, cannot resolve 3 ) shift == 100: max_iteration_stop; no shift found

4 ) shift == 101: sweld within sequence (which is used for shift calculation). not computable –> TODO try another position afterwards

5 ) shift < 0: missing weld or missing jump. (always test missing jump first)

search for swelds in eos

if sweld exist (always check for missing weld again, after one sweld is dropped)

if exactly one –> try else –> try shortest until either 5 times tried or if shift is valid until shift is reached if error moves only one index –> another not detected sweld or missing jump

else then missing jump –> typically at pos_err because two following welds are “added”

TODO check and solve

  1. shift > 0: additional jump

    TODO

errortype ==

0: shift is null, does not work 1: missing weld assumed between pos_io and true_pos_err 2: missing weld assumed between pos_io and pos_err 3: missing jump assumed between pos_io and true_pos_err 4: missing jump assumed between pos_io and pos_err 5: broken weld assumed between pos_io and pos_err -1: could not determine

Args: df, pos_err, error_treshold Returns: error_type, shift, pos_err

prosi3d.preprocessing.io module

prosi3d.preprocessing.io.dropFileDuplicates(lst, sep='_')[source]
prosi3d.preprocessing.io.filesInFolder_simple(dir, typ='h5')[source]

Helper function to select all files by file ending Args: dir, typ=’h5’ Returns: validfiles

prosi3d.preprocessing.io.folder2Files(path, stdprnt=1)[source]

Use path as dir to project. Put inside *openjz.txt file, *.openjobfile and *_param.csv This functions helps to organize files in projectfolder by file-type Args: filepath Returns: eostxtfile, paramfile, jobfile, vecdir

prosi3d.preprocessing.io.listpar(path)[source]

helper function to create csv with all occuring parameter names to then add DOE values manually to this file before calling vecTiming_hdf()

Args: path Returns: <save empty parameter file with partnumbers (partId = partnumber+1) and assigned parameter names>

prosi3d.preprocessing.layer module

prosi3d.preprocessing.layer.assign_weld_speed(path, eos_layer)[source]

input path and eos_layer with corrected exposure types –> correctContourExpTypes() add welding speeds to each line based on parameter file Args: path, eos_layer Returns: eos_layer

prosi3d.preprocessing.layer.correctContourExpTypes(eos_layer)[source]

correct wrong expType of contours if x1 and y1 equal x0 and y0 of following vectors for expTypes 1, 2, 3 Nicht korrigierte Upskin downskins könnten der Fehler in den bisherigen versionen gewesen sein! (15.11.2022)

Args: eos_layer Returns: eos_layer

prosi3d.preprocessing.layer.correctLayChange(path, files=[])[source]

Finds layerchanges by unique “laser-off” signal using savitzky-golay-filter and its increase dx If 1500 values are inside boarders then layerchange is found. resulting time delay is 0,03 s beyond laser off

TODO: add pausing for 50000 values before next trigger is allowed (peaks in rawsignal sometimes cause double triggering)

Args: time, signal Returns: times, lines

prosi3d.preprocessing.layer.errorLayer(folder_stl)[source]

Calculate all first layers above missing layers and return sorted list without duplicates

prosi3d.preprocessing.layer.labelLayer_bindingError(file, partids, polygons)[source]

open xytime for lay filter partId which has failure end / first true layer ask all resulting points if in polygon

prosi3d.preprocessing.layer.loopLayerMatchList(path, matchlist, partlist, layer_partids, what='ttldir', correction=0)[source]
prosi3d.preprocessing.layer.reshapeLayerPartIds(error_layers, base_and_layers, partlist)[source]

create an array with layers above each error and relevant partIds within that layers

prosi3d.preprocessing.layer.reshape_eos_layer_file(eos_layer_file)[source]

Reshapes dataset where two lines represent one weld into a “one line represents one weld” shape Args: eos_layer_file Returns: eos_layer

prosi3d.preprocessing.layer.ttl2Welds(layer, path, tresh1=1, tresh2=-1)[source]

New version of tJumpTTL() returning dataframe for ttlweld class. ttlweld class equals weld class where one entry represents one weld. duration returned is maybe one sampling width too long - (substraction added 28.11.2022) 16.11.2022

Args: layer (integer), path, tresh1=1, tresh2=-1 Returns: lsr_strt_jmp_len_jmp_strt_lsr_len (pandas dataframe)

prosi3d.preprocessing.openjz module

prosi3d.preprocessing.openjz.listpar_stl(path)[source]

helper function editet to return all stl file names from openjob file

Args: path Returns: partlist

prosi3d.preprocessing.openjz.readDf(path)[source]

Reads txt-File exported via EOSPRINTAPI from *openjz.txt build-preview-file. Deletes non numeric numbers and calculates layerchanges. returns df: array with vector-tuple in rows and columns: x_mm, y_mm, exposureType, partId returns layers: list of layerchangelineindexes starting with change from 1 to 2 returns vecdir where eosprint_layer files are stored via function df2layers

Args: eostxtfilepath Returns: df, layers, vecdir

prosi3d.preprocessing.preprocessing module

prosi3d.preprocessing.preprocessing.loopMain(path, correction=0)[source]

Checks matching eosprint_layer and ch4raw_ files in subfolders of path and loops redefinelaserpathstarts() over those matching files. Use correction!=0 layer numbers do not equal, e.g. eosprint_layer00001 belongs to ch4raw_00003: correction=2

Args: path, correction=0 Returns: matches

prosi3d.preprocessing.preprocessing.main(path, layer)[source]

executed layerwise. opens unchanged eosprint_layer file. runs some corrections. create eosweld and ttlweld classes and run main_redefinelaserpathstarts(), whichs updates eoswelds restructure eoswelds to dataframe update t1 from calculated temporal length to timerow “weldend” time value write eos_print_corr file

prosi3d.preprocessing.ttl module

prosi3d.preprocessing.ttl.tJumpTTL(layer, path, sampling_ms=0.02)[source]

03.11.2022 modified to input path as argument

Gives dataframes with temporal lengths and positions of found jumps and laservectors in ttl signal of entered layer.

Procedure: laser is on when ttl values above thresholds filter those and copy indexes to column calculate difference of idx column where idx-difference is > 1 a jump was in between and vice versa -> row gives start of weld and diff_idx length of jump to this row/time filtered and multiplied with sampling time gives temporal length of jump

Args: layer,sampling_ms=0.02 Returns: jmp_strt_lsr_len, lsr_strt_jmp_len

prosi3d.preprocessing.ttl.test_len_diff(df)[source]
prosi3d.preprocessing.ttl.update_ttlid_solved(df, welds, ttlwelds)[source]

Overwrite ttlid with index of df. Update weld.id

Return: welds

prosi3d.preprocessing.utils module

prosi3d.preprocessing.utils.chk_ascending(pandas_series)[source]
prosi3d.preprocessing.utils.class_objects_to_dataframe(welds_updated)[source]

Helper function to convert list of objects to a 2d-representaion (pandas dataframe) using all attributes as columns and object as line.

Args: list of objects Returns: pandas dataframe

prosi3d.preprocessing.utils.getPnts(fname, pnts=4)[source]

Works at the moment only with

prosi3d.preprocessing.utils.getPolygons(path, partlist)[source]
prosi3d.preprocessing.utils.getZ(fname)[source]

Returns layer numbers of first layer above all binding errors of one stltxt file

prosi3d.preprocessing.utils.point_in_polygon(polygon, point)[source]

Raycasting Algorithm to find out whether a point is in a given polygon. Performs the even-odd-rule Algorithm to find out whether a point is in a given polygon. This runs in O(n) where n is the number of edges of the polygon.

Parameters:
  • polygon – an array representation of the polygon where polygon[i][0] is the x Value of the i-th point and polygon[i][1] is the y Value.

  • point – an array representation of the point where point[0] is its x Value and point[1] is its y Value

Returns:

whether the point is in the polygon (not on the edge, just turn < into <= and > into >= for that)

prosi3d.preprocessing.utils.setcolor(expType)[source]

defines colors regarding eos exposureType number. called by function pfeile().

Args: expType

prosi3d.preprocessing.utils.shapePolygon(fname)[source]

iterative sorting by nearest next point to create a polygon with points in the right row. does not work for star-shaped areas -> then better use alphashape or sth else for sorting.

prosi3d.preprocessing.visualisation module

prosi3d.preprocessing.visualisation.vectors_view(lay, path=0, pdf=1, color_vector=0, jumps=0, solved_vectors=False)[source]

generates graphical representation of eosprint makro scan vectors either via qt5 or saved as pdf (pdf=1 saves pdf instead of qt5 inline plot) jumps = 1 swaps order to show jumps color_vector = >123< colors vector number 123 calls function setcolor() give it a layer number and project path or give it a filepath

Args: lay,path=0,pdf=1,color_vector=0,jumps=0,solved_vectors=False Returns: <none>

prosi3d.preprocessing.welds module

class prosi3d.preprocessing.welds.ParameterSpeed(param_name, infill_down, infill_std, infill_up, contour_down, contour_std, contour_up, contour_simple, edge, partboundary=None, support=None, gap=None, jump=None)[source]

Bases: object

class prosi3d.preprocessing.welds.Part(prtId, param_name)[source]

Bases: object

class prosi3d.preprocessing.welds.Weld(x0, y0, x1, y1, expType, prtId, x0_next, y0_next, speed, id, ttlid=None, t0=None, t1=None, t1ttl=None)[source]

Bases: object

angle()[source]
changeExp()[source]
dis()[source]
dis_jmp()[source]
duration_ms()[source]
dx()[source]
dx_jmp()[source]
dy()[source]
dy_jmp()[source]
class prosi3d.preprocessing.welds.Weld_ttl(idx0_weld, t0_weld, diff_idx_next_jump, diff_ms_next_jump, time2power_weld, idx0_next_jump, t0_next_jump, diff_idx_weld, diff_ms_weld, time2power_next_jump, id)[source]

Bases: object

prosi3d.preprocessing.welds.chk_err_move(pos_err, df_new)[source]

calculates error values for dataframe and returns movement of error. positive value -> error moves forward -> good solution

Args: pos_err, df_new Returns: (pos_err_new - pos_err)

prosi3d.preprocessing.welds.compare_temporal_weld_len(ttlid, welds, ttlwelds)[source]
prosi3d.preprocessing.welds.corresponding_error(df)[source]

Calculate error between eos and ttl relative and absolute error

Args: df Retruns: df

prosi3d.preprocessing.welds.corresponding_welds(welds, ttlwelds)[source]

create lists for dataframe by iterating welds and sum up weld times of welds without measureable jump afterwards based on ttlid

Args: welds Retruns: dataframe

prosi3d.preprocessing.welds.del_shortest(df, pos_io, pos_err)[source]
prosi3d.preprocessing.welds.error_position(df, min_weld_len=1, error_treshold=0.2)[source]

returns position (idx) of first wrong vector (pos_err) in eos (error_rel > error_treshold) that is not too short (> min_weld_len) pos_err is not the exact index of the error, but an index where allocation eos-ttl is definitively wrong called functon error_determination() tries to find out error type, shift and correct allocation for pos_err

Args: df, min_weld_len=1, error_treshold=0.2 Returns: pos_err, pos_io, true_pos_err

prosi3d.preprocessing.welds.find_unique_welds_eos(df, pos_err, min_weld_len=5, error_treshold=0.05, ntimes=2, col='dura_eos')[source]

find welds in eos that are kind of unique / outstanding in time row that differ (temporal length) to prv and next welds afterwards <pos_err> by ntimes * error_threshold

len typical error 10 < 0.01 5 < 0.02 2 < 0.05 1 < 0.1

Args: df, pos_err, min_weld_len=5, error_treshold=0.05, ntimes=2 Returns: unique_welds

prosi3d.preprocessing.welds.io_position(df, error_position=-1, min_weld_len=5, error_treshold=0.05, ntimes=2)[source]

finds index of welds with temporal length missmatch (relative error) of error_treshold, temporal target length (eos) > min_weld_len until index of error_position or end of dataframe (-1), which are more than ntimes of error_treshold longer or shorter compared to welds before and after. Returns only last correct single peak (not “absolut last” io position)

Args: df, error_position=-1, min_weld_len=5, error_treshold=0.05, ntimes=2 Retruns: iopos

prosi3d.preprocessing.welds.main_redefinelaserpathstarts(welds, ttlwelds)[source]

Motivation: count of eoswelds and ttlwelds differ because of measurement error

Am 26.01. verändert und solver und error_determination vereinigt

Create dataframe from classes and compute temporal weldlength error While as long as count of eoswelds and ttlwelds differ

Calculate first/next error position and try to solve it incl. checks for success recalculate dataframe

calculate final error position and if completed calculate eos welds_updated return corrected eoswelds if full dataframe could succeeded

Args: eoswelds and ttlwelds as classes Returns: corrected eoswelds

prosi3d.preprocessing.welds.matching_sequence(df, seq_strt_eos, seq_len=5, max_iter=4, mode=-1)[source]

This function should find the shift of a sequence using iterativ trial of shifts in one direction. may repeat in the other direction (mode). standard is backwards (missing measured weld). will may not find a result if an error is within the sequence (e.g. too short non measurable weld) welds with nominal length < 1 ms will be ignored (variance too high) diffs prv and nxt < 0.05 will be ignored (variance too high) compare a sequence of df by comparation of duration, diff previous and diff next. try several shifts iteratively, e.g. up to three to find true shift Return -1: means sequence in ttl is shifted by one backwards (one missing weld in ttl against eos before sequence) Return 100: means no shift value was found within iteration count

Changelog: 07.02.2023 error_treshold=0.1 -> 0.075 and abort criteria len(unique_welds) == 0 -> e is null -> cannot find

TODO find additionally by maxima if values differ at least by x % ? does only work if maximum is in sequence (umkehrpunkt)

Args: df, seq_strt_eos, seq_len=5, max_iter=4, mode=-1 Returns: shift

TODO error codes einführen für die verschiedenen abbrüche

prosi3d.preprocessing.welds.matching_unique(df, pos_err, min_weld_len=5, error_treshold=0.05, ntimes=2, win=10, max_iter=1)[source]
find outstanding weld in eos

length is within +/- win unique prev and next differ ntimes*error_treshold nominal length is above 5 ms length is present in +/- win only once not first or last position in window

find same unique weld in ttl measurement

Version: 07.12.2022

Returns: shift, unique_welds_eos.iloc[0].index

prosi3d.preprocessing.welds.rel_error(eos, ttl)[source]

compute relative error of two arrays / numbers

prosi3d.preprocessing.welds.swelds(df, crit_len=0.042)[source]

find really short welds “swelds” based on eos target legnth, that are maybe not measured. crit_len should be 2x sampling distance Args: df, crit_len=0.042) Returns: swelds

prosi3d.preprocessing.welds.update_ttlid_nonjumps(welds)[source]

Update ttlid in weld class based on zerodistance after weld (contours). before: ttlid 1,2,3,4,5,6, … know: ttlid 1,2,3,3,3,4,5,6, … Args: welds Returns: welds

Module contents