Skip to content

Commit

Permalink
update release 3.26.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mfroeling committed Aug 1, 2024
1 parent d7fbdac commit 7baf68b
Show file tree
Hide file tree
Showing 7 changed files with 10,727 additions and 20,022 deletions.
43 changes: 36 additions & 7 deletions QMRITools/Kernel/MaskingTools.wl
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ DilateMask::usage=
SegmentMask::usage =
"SegmentMask[mask, n] divides a mask in n segments along the slice direction, n must be an integer. The mask is divided in n equal parts where each parts has the same number of slices."

SegmentationVolume::usage =
"SegmentationVolume[seg] calculates the volume of each label in the segmentation."


ROIMask::usage =
"ROIMask[maskdim, {name->{{{x,y},slice}..}..}] crates mask from coordinates x and y at slice.
Expand Down Expand Up @@ -556,11 +559,16 @@ SelectReplaceSegmentations[segm_, labSel_, labNew_] := Block[{split, seg, lab, s
{seg, lab} = If[split, SplitSegmentations[segm], segm];

sel = MemberQ[labSel, #] & /@ lab;
seg = Transpose[Pick[Transpose[seg], sel, True]];
lab = Pick[lab /. Thread[labSel->labNew], sel, True];
or = Ordering[lab];

If[split, MergeSegmentations[seg, lab], {seg[[All,or]], lab[[or]]}]
If[AllTrue[sel, # === False &],
If[split, 0 MergeSegmentations[seg, lab], {0 seg[[All,1]], {}}]
,
seg = Transpose[Pick[Transpose[seg], sel, True]];
lab = Pick[lab /. Thread[labSel->labNew], sel, True];
or = Ordering[lab];

If[split, MergeSegmentations[seg, lab], {seg[[All,or]], lab[[or]]}]
]
]


Expand All @@ -570,9 +578,11 @@ SelectReplaceSegmentations[segm_, labSel_, labNew_] := Block[{split, seg, lab, s

Options[SmoothSegmentation] = {MaskComponents -> 1, MaskClosing -> 5, MaskFiltKernel -> 2, MaskDilation -> 0, SmoothItterations->3}

SyntaxInformation[SmoothSegmentation] = {"ArgumentsPattern" -> {_, OptionsPattern[]}};
SyntaxInformation[SmoothSegmentation] = {"ArgumentsPattern" -> {_, _., OptionsPattern[]}};

SmoothSegmentation[maskIn_, opts:OptionsPattern[]] :=
SmoothSegmentation[maskIn_, opts:OptionsPattern[]] :=SmoothSegmentation[maskIn, All, opts]

SmoothSegmentation[maskIn_, what_, opts:OptionsPattern[]] :=
Block[{smooth,obj, md, masks, labs},
smooth = OptionValue[MaskFiltKernel];
obj = OptionValue[MaskComponents];
Expand All @@ -586,7 +596,7 @@ SmoothSegmentation[maskIn_, opts:OptionsPattern[]] :=
masks = Transpose[SparseArray[Round@masks]];

(*Get smoothed or non smoothed masks*)
masks = SmoothMask[#, Sequence@@FilterRules[{opts}, Options[SmoothMask]]]&/@masks;
masks[[what]] = SmoothMask[#, Sequence@@FilterRules[{opts}, Options[SmoothMask]]]&/@masks[[what]];

(*remove the overlaps*)
masks = Transpose@RemoveMaskOverlapsI[SparseArray[masks]];
Expand Down Expand Up @@ -688,6 +698,25 @@ SegmentMask[mask_, seg_?IntegerQ] := Block[{pos, f, l, sel, out},
]


(* ::Subsubsection::Closed:: *)
(*SegmentationVolume*)


SyntaxInformation[SegmentationVolume] = {"ArgumentsPattern" -> {_, _.}};

SegmentationVolume[seg_] := SegmentationVolume[seg, {0, 0, 0}]

SegmentationVolume[seg_, vox : {_?NumberQ, _?NumberQ, _?NumberQ}] :=
Block[{vol},
vol = If[vox === {0, 0, 0}, 1, N@((Times @@ vox)/1000)];
vol Total[Flatten[#]] & /@ Switch[ArrayDepth[seg],
3, Transpose[First@SplitSegmentations[seg]],
4, Transpose[seg],
_, Return[$Failed]
]
]


(* ::Subsection::Closed:: *)
(*ROIMask*)

Expand Down
110 changes: 60 additions & 50 deletions QMRITools/Kernel/PlottingTools.wl
Original file line number Diff line number Diff line change
Expand Up @@ -1829,56 +1829,62 @@ PlotContour[dati_, vox_, opts:OptionsPattern[]] := Block[{

If[ArrayDepth[dati]===4,
SeedRandom[12345];
Show[PlotContour[#[[1]], vox, ContourColor->#[[2]], opts
]&/@ Transpose[{Transpose[dati], RandomColor[Length@First@dati]}]]
Show[PlotContour[#[[1]], vox, ContourColor->#[[2]], opts]&/@ Transpose[{Transpose[dati], RandomColor[Length@First@dati]}]]
,
smooth = OptionValue[ContourSmoothRadius];
reso = OptionValue[ContourResolution];
scale = OptionValue[ContourScaling];
color = OptionValue[ContourColor];
opac = OptionValue[ContourOpacity];

dim = Dimensions@dati;
pad = 10;
data = ArrayPad[dati, pad];
If[N[Max[dati]] === 0.,
Graphics3D[],

{data, crp} = AutoCropData[data];
If[IntegerQ[smooth], If[smooth>0, data = GaussianFilter[data, smooth]]];

col = If[ColorQ[color], color, If[color==="Random", RandomColor[], GrayLevel[1.]]];
style = Directive[{Opacity[opac], col, Specularity[Lighter@Lighter@col, 5]}];

colfunc = If[! ArrayQ[color],
Automatic,
ran = OptionValue[ContourColorRange];
ran = If[ran === Automatic,
Quantile[DeleteCases[N@Flatten[color], 0.], {0.02, 0.98}],
ran];
coldat = Rescale[color, ran];
Function[{z, y, x},
ColorData[OptionValue[ColorFunction]][
coldat[[Clip[Round[x], {1, dim[[3]]}],
Clip[Round[y], {1, dim[[2]]}], Clip[Round[z], {1, dim[[1]]}]]]]
]
];
dim = Dimensions@dati;
pad = 2 (smooth + 1);

{data, crp} = AutoCropData[dati, CropPadding->0];
data = ArrayPad[data, pad];

reso = Reverse@Round[(vox Dimensions[data]) / Switch[reso, Automatic, Reverse[vox], _, reso]];
scale = Switch[scale, "World", Reverse[vox], _, {1,1,1}];
range = Reverse[Partition[crp, 2]] - pad - {{1, 0}, {1, 0}, {1, 0}};
dim = Reverse[dim];

ListContourPlot3D[data,
Contours -> {0.5},
Mesh -> False, BoundaryStyle -> None, Axes -> True,
SphericalRegion -> True,
ColorFunctionScaling -> False, ColorFunction -> colfunc,
ContourStyle -> style, Lighting -> "Neutral",
If[IntegerQ[smooth], If[smooth>0, data = GaussianFilter[data, smooth]]];
data = SparseArray[data];

MaxPlotPoints -> reso,
ImageSize -> 300,
DataRange -> scale range,
BoxRatios -> scale dim,
PlotRange -> Thread[{0, scale dim}]
col = If[ColorQ[color], color, If[color==="Random", RandomColor[], GrayLevel[1.]]];
style = Directive[{Opacity[opac], col, Specularity[Lighter@Lighter@col, 5]}];

colfunc = If[! ArrayQ[color],
Automatic,
ran = OptionValue[ContourColorRange];
ran = If[ran === Automatic,
Quantile[DeleteCases[N@Flatten[color], 0.], {0.02, 0.98}],
ran];
coldat = Rescale[color, ran];
Function[{z, y, x},
ColorData[OptionValue[ColorFunction]][
coldat[[Clip[Round[x], {1, dim[[3]]}],
Clip[Round[y], {1, dim[[2]]}], Clip[Round[z], {1, dim[[1]]}]]]]
]
];

reso = Reverse@Round[(vox Dimensions[data]) / Switch[reso, Automatic, Reverse[vox], _, reso]];
scale = Switch[scale, "World", Reverse[vox], _, {1,1,1}];

range = Reverse[Partition[crp, 2]] + {{-pad - 1, pad}, {-pad - 1, pad}, {-pad - 1, pad}};
dim = Reverse[dim];

ListContourPlot3D[data,
Contours -> {0.4},
Mesh -> False, BoundaryStyle -> None, Axes -> True,
SphericalRegion -> True,
ColorFunctionScaling -> False, ColorFunction -> colfunc,
ContourStyle -> style, Lighting -> "Neutral",

MaxPlotPoints -> reso,
ImageSize -> 300,
DataRange -> scale range,
BoxRatios -> scale dim,
PlotRange -> Thread[{0, scale dim}]
]
]
]
]
Expand Down Expand Up @@ -1907,20 +1913,24 @@ PlotSegmentations[seg_, bone_, vox_, opts : OptionsPattern[]] := Block[{
{smooth, cols, size, ranCol, op, res} = OptionValue[{ContourSmoothRadius, ColorFunction, ImageSize, RandomizeColor, ContourOpacity, ContourResolution}];

plotb = If[bone === None, Graphics3D[],
PlotContour[Unitize[bone], vox, ContourColor -> Gray, ContourOpacity -> 1, ContourSmoothRadius -> smooth, ContourResolution->res]
PlotContour[If[ArrayDepth[bone]===3, Unitize@bone, Unitize@Total@Transpose@bone], vox,
ContourColor -> Gray, ContourOpacity -> 1, ContourSmoothRadius -> smooth, ContourResolution->res]
];

segM = If[ArrayDepth[seg]===3, First@SplitSegmentations[seg], seg];
nSeg = Length@First@segM;
rSeg = Range[nSeg];
plotm = If[N[Max[seg]] === 0.,
Graphics3D[],

If[ColorQ[cols],
cols = ConstantArray[cols, nSeg];,
cols = Reverse[ColorData[OptionValue[ColorFunction]] /@ Rescale[rSeg]];
If[ranCol, SeedRandom[1234]; cols = cols[[RandomSample[rSeg]]]];
];
segM = If[ArrayDepth[seg]===3, First@SplitSegmentations[seg], seg];
nSeg = Length@First@segM;
rSeg = Range[nSeg];

plotm = Show[Table[PlotContour[segM[[All, i]], vox, ContourColor -> cols[[i]], ContourOpacity -> op, ContourSmoothRadius -> smooth, ContourResolution->res], {i, 1, nSeg}]];
If[ColorQ[cols],
cols = ConstantArray[cols, nSeg];,
cols = Reverse[ColorData[OptionValue[ColorFunction]] /@ Rescale[rSeg]];
If[ranCol, SeedRandom[1234]; cols = cols[[RandomSample[rSeg]]]];
];
Show[Table[PlotContour[segM[[All, i]], vox, ContourColor -> cols[[i]], ContourOpacity -> op, ContourSmoothRadius -> smooth, ContourResolution->res], {i, 1, nSeg}]]
];

Show[plotm, plotb, ViewPoint -> Front, ImageSize -> size, Boxed -> False, Axes -> False, SphericalRegion -> False]
]
Expand Down
10 changes: 2 additions & 8 deletions QMRITools/Kernel/ProcessingTools.wl
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,7 @@ Options[JoinSets]={

SyntaxInformation[JoinSets] = {"ArgumentsPattern" -> {_, _, OptionsPattern[]}};

JoinSets[data: {_?ArrayQ ..} over_, opts:OptionsPattern[]]:=JoinSets[data, over, {1,1,1}, opts]
JoinSets[data: {_?ArrayQ ..}, over_, opts:OptionsPattern[]]:=JoinSets[data, over, {1,1,1}, opts]

JoinSets[data: {_?ArrayQ ..}, over_, vox_, OptionsPattern[]]:=Block[
{dat, mon, overlap, motion, pad, normalize, depth, meth, target, normover, ran},
Expand Down Expand Up @@ -1194,7 +1194,7 @@ CorrectJoinSetMotion[input_, vox_, over_, OptionsPattern[]] := Module[

(*get the input*)
pad = OptionValue[PaddOverlap];
mon = OptionVAlue[MonitorCalc];
mon = OptionValue[MonitorCalc];
depth = ArrayDepth[input];

(*data which will be joined, make all data sets 4D*)
Expand Down Expand Up @@ -1226,26 +1226,20 @@ CorrectJoinSetMotion[input_, vox_, over_, OptionsPattern[]] := Module[
(*pad to allow motion*)
d1 = PadLeft[d1, dim];
maskd1 = PadLeft[maskd1, dim];

(*get the seconds overlap stac*)
d2 = sets[[n + 1, -overp ;;,1]];
maskd2 = Dilation[#, 3] &/@ Mask[d2,2];
(*pad to allow motion*)
d2 = PadLeft[d2, dim];
maskd2 = PadLeft[maskd2, dim];

maskd1 = maskd2 = Dilation[maskd1 maskd2, 1];

(*get the number of samples for the registration*)
samp = Round[((Total@Flatten@maskd1)+(Total@Flatten@maskd2))/20];

(*perform the registration*)
sets[[n + 1]] = Last@regFunc[{d1, maskd1, vox}, {d2, maskd2, vox}, {sets[[n + 1]], vox},
MethodReg -> "rigid", Iterations -> 300, NumberSamples -> samp,
PrintTempDirectory -> False, InterpolationOrderReg -> 1];

sets[[n+1]] = MaskData[sets[[n+1]], Dilation[Mask[NormalizeMeanData[sets[[n+1]]], .5], 2]];

, {n, 1, nmax - 1}];

(*output the data, make the 3D data 3D again*)
Expand Down
Loading

0 comments on commit 7baf68b

Please sign in to comment.