Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
276 changes: 138 additions & 138 deletions gecatsim/clib_build/src/analytic_projector.c

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions gecatsim/clib_build/src/analytic_projector.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ int n_row_oversample = 1;
int n_col_oversample_add_xtalk = 1;
int n_row_oversample_add_xtalk = 1;

struct module_info
struct analytic_module_info
{
double *Height;
double *Width;
Expand All @@ -43,7 +43,7 @@ struct module_info
int moduleOverlapType;
};

struct module_info modules = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0};
struct analytic_module_info analytic_modules = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0};

struct pnt
{
Expand All @@ -61,7 +61,7 @@ struct bounding_info

struct bounding_info bounding = {NULL,NULL};

struct phantom_info
struct analytic_phantom_info
{
int numObjects;
int *objectType;
Expand All @@ -77,7 +77,7 @@ struct phantom_info
double xbounds[2];
};

struct phantom_info phantom = {0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,{0,0}};
struct analytic_phantom_info analytic_phantom = {0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,{0,0}};

struct material_info
{
Expand All @@ -86,7 +86,7 @@ struct material_info
double *muTable;
};

struct material_info materials = {0,0,NULL};
struct material_info analytic_materials = {0,0,NULL};

struct projector_args
{
Expand Down
4 changes: 2 additions & 2 deletions gecatsim/clib_build/src/phantom.tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
typedef struct phantomlval {
double val;
double vec[3];
char str[128];
char str[2048];
} PHANTOMLVAL;

#endif
Expand Down Expand Up @@ -290,7 +290,7 @@ typedef struct phantomlval {
typedef union YYSTYPE {
double val;
double vec[3];
char str[128];
char str[2048];
} YYSTYPE;
/* Line 191 of yacc.c. */
//#line 283 "phantom.tab.cpp"
Expand Down
2 changes: 1 addition & 1 deletion gecatsim/clib_build/src/phantom.tab.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
typedef union YYSTYPE {
double val;
double vec[3];
char str[128];
char str[2048];
} YYSTYPE;
/* Line 1275 of yacc.c. */
#line 113 "phantom.tab.hpp"
Expand Down
2 changes: 2 additions & 0 deletions gecatsim/pyfiles/C_Projector_SetData.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def C_Projector_SetData(cfg, viewId, subViewId):
def get_projector_id(cfg):
if not isinstance(cfg.phantom.callback, list):
phantom_callbacks = [cfg.phantom.callback]
elif isinstance(cfg.phantom.callback, list) and isinstance(cfg.phantom.callback[0], list):
phantom_callbacks = cfg.phantom.callback[cfg.viewId]
else:
phantom_callbacks = cfg.phantom.callback
projectorIDs = []
Expand Down
3 changes: 2 additions & 1 deletion gecatsim/pyfiles/C_Projector_Voxelized.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ def C_Projector_Voxelized(cfg, viewId, subViewId):
unused7 = 7
freeTheMemory = 0

if viewId==cfg.sim.stopViewId and subViewId==cfg.sim.subViewCount-1 \
# ZJY recalcPht is helpful in reducing memory usage in dynamic phantom
if (cfg.physics.recalcPht or (viewId==cfg.sim.stopViewId and subViewId==cfg.sim.subViewCount-1))\
and srcId==src.nSamples-1 and matId==cfg.phantom.numberOfMaterials-1:
freeTheMemory = 1

Expand Down
94 changes: 73 additions & 21 deletions gecatsim/pyfiles/CommonTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ def make_col(a):
return a


def feval(func_name, *args):
def feval(funcName, *args):
module_paths = [
func_name,
f"gecatsim.pyfiles.{func_name}",
f"gecatsim.pyfiles.FlatPanel.{func_name}"
funcName,
f"gecatsim.pyfiles.{funcName}",
f"gecatsim.pyfiles.FlatPanel.{funcName}",
f"gecatsim.src.app.pyfiles.{funcName}"
]

module = None
Expand All @@ -42,15 +43,15 @@ def feval(func_name, *args):
continue

if module is None:
raise ImportError(f"Could not import module: {func_name}. Tried paths: {module_paths}")
raise ImportError(f"Could not import module: {funcName}. Tried paths: {module_paths}")

# Extract the function name (the part after the last dot)
func_name_only = func_name.split('.')[-1]
funcName_only = funcName.split('.')[-1]

try:
func = getattr(module, func_name_only)
func = getattr(module, funcName_only)
except AttributeError:
raise AttributeError(f"Function '{func_name_only}' not found in module '{module.__name__}'")
raise AttributeError(f"Function '{funcName_only}' not found in module '{module.__name__}'")

return func(*args)

Expand All @@ -74,16 +75,35 @@ def load_C_lib():


class emptyCFG:
pass

def __str__(self):
attrs = ', '.join(f"{key}={value!r}" for key, value in self.__dict__.items())
return f"{self.__class__.__name__}({attrs})"

def __repr__(self):
return self.__str__()



import sys

class PathHelper:
def __init__(self):
self._base_dir = os.getcwd()
# Locate paths of lib and data.
self.paths = {}
self.paths["main"] = os.path.dirname(os.path.abspath(__file__))
self.paths["top"] = os.path.split(self.paths["main"])[0]

# Handle PyInstaller bundled environment
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
# Running as compiled executable
bundle_dir = sys._MEIPASS
self.paths["main"] = os.path.join(bundle_dir, 'app', 'pyfiles')
self.paths["top"] = os.path.join(bundle_dir, 'app')
else:
# Running as normal Python script
self.paths["main"] = os.path.dirname(os.path.abspath(__file__))
self.paths["top"] = os.path.split(self.paths["main"])[0]

self.paths["bowtie"] = os.path.join(self.paths["top"], 'bowtie')
self.paths["cfg"] = os.path.join(self.paths["top"], 'cfg')
self.paths["dose"] = os.path.join(self.paths["top"], 'dose')
Expand Down Expand Up @@ -259,7 +279,6 @@ def source_cfg(*para):

# initialize structs in cfg and structs
attrList = ['sim', 'det', 'detNew', 'src', 'srcNew', 'spec', 'protocol', 'scanner', 'phantom', 'physics', 'recon', 'dose']

for attr in attrList:
# Ensure cfg has the attribute
if not hasattr(cfg, attr):
Expand Down Expand Up @@ -381,27 +400,60 @@ def overlap2d(oldimg, old_pos_x, old_pos_y, pos_x, pos_y):
def rawread(fname, dataShape, dataType):
# dataType is for numpy, ONLY allows: 'float'/'single', 'double', 'int'/'int32', 'uint'/'uint32', 'int8', 'int16'
# they are single, double, int32, uin32, int8, int16
with open(fname, 'rb') as fin:
data = fin.read()

# https://docs.python.org/3/library/struct.html
switcher = {'float': ['f', 4, np.single],
'single': ['f', 4, np.single],
'double': ['d', 8, np.double],
switcher = {'float': ['f', 4, np.float32],
'float32': ['f', 4, np.float32],
'single': ['f', 4, np.float32],
'double': ['d', 8, np.float64],
'int': ['i', 4, np.int32],
'uint': ['I', 4, np.uint32],
'int32': ['i', 4, np.int32],
'uint32': ['I', 4, np.uint32],
'uint8': ['B', 1, np.uint8],
'int8': ['b', 1, np.int8],
'int16': ['h', 2, np.int16]}
fmt = switcher[dataType]
data = struct.unpack("%d%s" % (len(data)/fmt[1], fmt[0]), data)

data = np.array(data, dtype=fmt[2])
fmt_char, byte_size, np_dtype = switcher[dataType]

# Use numpy.fromfile for direct binary reading - much faster
try:
data = np.fromfile(fname, dtype=np_dtype)
except:
# Fallback to manual reading if fromfile fails
with open(fname, 'rb') as fin:
raw_data = fin.read()
num_elements = len(raw_data) // byte_size
data = struct.unpack(f"{num_elements}{fmt_char}", raw_data)
data = np.array(data, dtype=np_dtype)

if dataShape:
data = data.reshape(dataShape)

return data

# with open(fname, 'rb') as fin:
# data = fin.read()

# # https://docs.python.org/3/library/struct.html
# switcher = {'float': ['f', 4, np.single],
# 'float32': ['f', 4, np.float32],
# 'single': ['f', 4, np.single],
# 'double': ['d', 8, np.double],
# 'int': ['i', 4, np.int32],
# 'uint': ['I', 4, np.uint32],
# 'int32': ['i', 4, np.int32],
# 'uint32': ['I', 4, np.uint32],
# 'uint8': ['B', 1, np.uint8],
# 'int8': ['b', 1, np.int8],
# 'int16': ['h', 2, np.int16]}
# fmt = switcher[dataType]
# data = struct.unpack("%d%s" % (len(data)/fmt[1], fmt[0]), data)

# data = np.array(data, dtype=fmt[2])
# if dataShape:
# data = data.reshape(dataShape)

# return data

def rawwrite(fname, data):
with open(fname, 'wb') as fout:
Expand Down
2 changes: 1 addition & 1 deletion gecatsim/pyfiles/Detector_RayAngles_2D.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def Detector_RayAngles_2D(cfg):

xyzDet = nm.repmat(det.modCoords[m, :], nCells, 1) + \
det.cellCoords @ (np.c_[det.uvecs[m, :], det.vvecs[m, :]].T)
xyzR = xyzDet - nm.repmat(xyzSrc, nCells, 1);
xyzR = xyzDet - nm.repmat(xyzSrc, nCells, 1)

cellInd = range(startInd, startInd+nCells)
rayDistance[cellInd] = vectornorm(xyzR.T)
Expand Down
Loading
Loading