5
{$DEFINE noCOMPILEYOKE}
9
{$IFDEF Darwin}CarbonOpenDoc,{$ENDIF}
14
lclintf,LCLType,//gettickcount ,LMessages
18
{$IFNDEF FPC} E_memmap,RXSpin,capmenu,Math,ToolWin,Messages,
23
SysUtils, Classes, Graphics, Controls, Forms, Dialogs,Menus,ComCtrls, ExtCtrls,
24
StdCtrls, GraphicsMathLibrary,ClipBrd,define_types, Spin,Buttons,
25
nifti_hdr,nifti_hdr_view,nifti_img, voismooth,
26
IniFiles,ReadInt,registry,stat,Distr,bet,mni,prefs,CropEdges,userdir,graphx,
27
GraphType,IntfGraphics, landmarks;
11
lclintf,LCLType,//gettickcount ,LMessages
19
LResources, fx8, cpucount, SysUtils, Classes, Graphics, Controls, Forms,
20
Dialogs, Menus, ComCtrls, ExtCtrls, StdCtrls, GraphicsMathLibrary, ClipBrd,
21
define_types, Spin, Buttons, nifti_hdr, nifti_hdr_view, nifti_img, voismooth,
22
IniFiles, ReadInt, registry, simpleipc, stat, Distr, bet, mni, prefs, CropEdges,
23
userdir, graphx, GraphType, IntfGraphics, landmarks;
31
27
PINtBuffer = ^TIntBuffer;
32
TIntBuffer = Array[0..6] of single;
28
TIntBuffer = Array[0..6] of single;}
230
217
procedure MNIMenuClick(Sender: TObject);
231
218
procedure N4DTraces1Click(Sender: TObject);
232
219
procedure NIIVOIClick(Sender: TObject);
233
//procedure OptimizeViewClick(Sender: TObject);
234
220
procedure PGImageCorDblClick(Sender: TObject);
235
221
procedure Preferences1Click(Sender: TObject);
236
222
procedure RescaleMenuClick(Sender: TObject);
237
223
procedure Resliceimage1Click(Sender: TObject);
238
224
procedure SaveasNIfTI1Click(Sender: TObject);
239
225
procedure SaveDialog1Close(Sender: TObject);
226
procedure SimpleIPCServer1Message(Sender: TObject);
240
227
procedure UpdateColorSchemes;
241
228
procedure UpdateTemplates;
242
229
procedure UpdateMRU;
272
259
Shift: TShiftState; X, Y: Integer);
273
260
procedure LUTdropLoad(var lLayer: integer);
274
261
procedure LUTdropSelect(Sender: TObject);
275
procedure ZoomDropChange(Sender: TObject);
262
procedure ZoomDropChange(Sender: TObject);
276
263
procedure ZoomDropSelect(Sender: TObject);
277
264
procedure ColorBarBtnMouseDown(Sender: TObject; Button: TMouseButton;
278
265
Shift: TShiftState; X, Y: Integer);
279
//procedure OptimizeViewMenuItemClick(Sender: TObject);
280
266
procedure Saveaspicture1Click(Sender: TObject);
281
267
procedure XBarBtnClick(Sender: TObject);
282
268
procedure XBarBtnMouseUp(Sender: TObject; Button: TMouseButton;
283
269
Shift: TShiftState; X, Y: Integer);
284
procedure XBarBtnMouseDown(Sender: TObject; Button: TMouseButton;
270
procedure XBarBtnMouseDown(Sender: TObject; Button: TMouseButton;
285
271
Shift: TShiftState; X, Y: Integer);
286
272
procedure AutoContrastBtnClick(Sender: TObject);
287
273
procedure RefreshImagesTimerTimer(Sender: TObject);
459
438
procedure TImgForm.CloseShareMem;
466
440
{$IFDEF COMPILEYOKE}
467
//shared memory release START
468
gShareIntBuf^[0] := gShareIntBuf^[0] -1;
469
lInstances := gShareIntBuf^[0];
470
if Assigned (FSharePtr) then
472
//if FOwnShm then zssss
473
if lInstances = 0 then begin
474
//last running instance - close shared memory
475
if shmctl (FShmId, IPC_RMID, nil) = -1 then
476
raise Exception.Create (strerror (errno));
478
//shared memory release END
441
SimpleIPCServer1.active := false;
442
SimpleIPCClient1.active := false;
482
446
procedure TImgForm.SetShareMem (lXmm,lYmm,lZmm: single);
485
if not gYoke then exit;
486
EMemMap.EnterCriticalSection;
488
SingleArrPtr(EMemMap.MemMap)^[1]:=(lXmm);
489
SingleArrPtr(EMemMap.MemMap)^[2]:=(lYmm);
490
SingleArrPtr(EMemMap.MemMap)^[3]:=(lZmm);
492
EMemMap.LeaveCriticalSection;
495
448
{$IFDEF COMPILEYOKE}
497
gShareIntBuf^[1] := (lXmm);
498
gShareIntBuf^[2] := (lYmm);
499
gShareIntBuf^[3] := (lZmm);
451
SendIPCFloats(SimpleIPCClient1,lXmm,lYmm,lZmm);
504
455
procedure TImgForm.CreateShareMem;
508
//shared memory acquire START
511
Key := ftok (PChar(GetModuleName(0)),Key {1}); //use UserID so each user gets separate pool of shared memory
512
// try to open existing shared memory
513
FShmId := shmget (Key, 0, 0);
516
// doesn't exist, create it
517
FShmId := shmget (Key, kShareSegmentSize,
518
IPC_CREAT or IPC_EXCL or AccessMode);
520
raise Exception.Create (strerror (errno));
525
// attach to shared memory
526
FSharePtr := shmat (FShmId, nil, 0);
527
if Integer(FSharePtr) = -1 then
530
raise Exception.Create (strerror (errno));
532
gShareIntBuf := FSharePtr;
534
gShareIntBuf^[0] := 0;
535
gShareIntBuf^[0] := gShareIntBuf^[0]+1;
536
SetShareMem (gXProj,gYProj,gZProj);
541
//CompileYoke not set
544
{$ELSE}//not FPC - must be Delphi
549
EMemMap:=TEMemMap.Create(Self);
550
EMemMap.CreateMutex('MRICROMUTEX2');
551
If NOT EMemMap.MapExisting('MRICROMAP2',SizeOf(SingleArr)) then begin
553
For I:=1 To kYokeItems do
556
If NOT EMemMap.CreateMemMap('MRICROMAP2',SizeOf(SingleArr),IArr^) then
557
EMemMap.RaiseMappingException;
458
startipcserver(SimpleIPCServer1,SimpleIPCClient1);
566
463
procedure TImgForm.YokeTimerTimer(Sender: TObject);
466
YokeTimer.Enabled := false;
468
if SimpleIPCServer1.Active then SimpleIPCServer1.PeekMessage(1,true);
568
473
lXmm,lYmm,lZmm: single;
569
474
lX,lY,lZ: integer;
571
caption := inttostr(888);
572
476
if not gYoke then begin
573
477
YokeTimer.Enabled := false;
1238
1142
ApplySaveDlgFilter(SaveDialog1);
1145
procedure TImgForm.SimpleIPCServer1Message(Sender: TObject);
1148
lXmm,lYmm,lZmm: single;
1152
if not GetIPCFloats(SimpleIPCServer1.StringMessage, lXmm,lYmm,lZmm) then
1154
MMToImgCoord(lX,lY,lZ,lXmm,lYmm,lZmm);
1155
if lX <> XViewEdit.value then XViewEdit.value := lX;
1156
if lY <> YViewEdit.value then YViewEdit.value := lY;
1157
if lZ <> ZViewEdit.value then ZViewEdit.value := lZ;
1158
XViewEditChange(nil);
1160
if SimpleIPCServer1.Active then SimpleIPCServer1.PeekMessage(1,true);
1241
1164
procedure Add2MRU (var lNewFilename: string); //add new file to most-recent list
1770
1693
lIntenStr[lLen-1] := ' ';
1771
1694
//StatusLabel.Caption := realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0)+'= '+lIntenStr;
1772
1695
Caption := realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0)+'= '+lIntenStr;
1774
// SetShareMem (lXmm,lYmm,lZmm);
1696
SetShareMem (lXmm,lYmm,lZmm);
1777
1699
procedure TImgForm.XViewEditChange(Sender: TObject);
1965
1887
end; //sortLTRB
1967
1889
procedure DrawEllipse (lImage: TImage;lRect: TRect; lShift: TShiftState; lPanel: integer);
1969
1893
ScaleBMP2Draw(gBGImg.VOIInvZoom, lRect.Left,lRect.Top,lPanel,Limage);
1970
1894
ScaleBMP2Draw(gBGImg.VOIInvZoom, lRect.Right,lRect.Bottom,lPanel,lImage);
1895
if ssShift in lShift then
1971
1899
if (ssCtrl in lShift) then
1972
FillRectFX8(gDrawImg,lRect.Left,lRect.Top,lRect.Right,lRect.Bottom,kVOI8bit)
1900
FillRectFX8(gDrawImg,lRect.Left,lRect.Top,lRect.Right,lRect.Bottom,i)
1974
FillEllipseFX8(gDrawImg,lRect.Left,lRect.Top,lRect.Right,lRect.Bottom,kVOI8bit);
1902
FillEllipseFX8(gDrawImg,lRect.Left,lRect.Top,lRect.Right,lRect.Bottom,i);
1975
1903
end; //DrawEllipse
2540
2468
lLabelStr := ' ';
2541
2469
if lVOI then //intensity min/max position are not important
2542
TextForm.Memo1.Lines.add(lLabelStr+'Area,N>0,%N>0')
2470
TextForm.MemoT.Lines.add(lLabelStr+'Area'+kTextSep+'N>0'+kTextSep+'%N>0')
2544
TextForm.Memo1.Lines.add(lLabelStr+'Area,N>0,%N>0,Sum>0,Mean>0,Max,MaxX,MaxY,MaxZ');
2472
TextForm.MemoT.Lines.add(lLabelStr+'Area'+kTextSep+'N>0'+kTextSep+'%N>0'+kTextSep+'Sum>0'+kTextSep+'Mean>0'+kTextSep+'Max'+kTextSep+'MaxX'+kTextSep+'MaxY'+kTextSep+'MaxZ');
2545
2473
//next initialize
2546
2474
if lShowFilename then
2547
lLabelStr := gMRIcroOverlay[lOverlayNum].HdrFileName+','
2475
lLabelStr := gMRIcroOverlay[lOverlayNum].HdrFileName+kTextSep
2549
2477
lLabelStr := '';
2550
2478
for lInc := 0 to kHistoBins do begin
2589
2517
lLocalMax[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalMax[lInc]);
2590
2518
lLocalSum[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalSum[lInc]);
2591
2519
ImgPosToMM(lLocalMaxPos[lInc], lXmm,lYmm,lZmm);
2592
TextForm.Memo1.Lines.Add(lLabelStr+ lLabelStr20[lInc] + ', ' + inttostr(lHisto[lInc])+','+floattostr( lHisto[lInc]/lRegionVol[lInc])
2593
+','+floattostr( lLocalSum[lInc])+','+floattostr( lLocalSum[lInc]/lRegionVol[lInc]) //Sum>0, mean>0
2594
+', ' + floattostr(lLocalMax[lInc])+','+floattostr(lXmm)+','+floattostr(lYmm)+','+floattostr(lZmm) );
2520
TextForm.MemoT.Lines.Add(lLabelStr+ lLabelStr20[lInc] + kTextSep + inttostr(lHisto[lInc])+kTextSep+floattostr( lHisto[lInc]/lRegionVol[lInc])
2521
+kTextSep+floattostr( lLocalSum[lInc])+kTextSep+floattostr( lLocalSum[lInc]/lRegionVol[lInc]) //Sum>0, mean>0
2522
+kTextSep + floattostr(lLocalMax[lInc])+kTextSep+floattostr(lXmm)+kTextSep+floattostr(lYmm)+kTextSep+floattostr(lZmm) );
2595
2523
end else if (lHisto[lInc] > 0) {necessarily also and (lRegionVol[lInc] > 0)} then
2596
TextForm.Memo1.Lines.Add(lLabelStr+ lLabelStr20[lInc] + ', ' + inttostr(lHisto[lInc])+','+floattostr( lHisto[lInc]/lRegionVol[lInc])) ;
2524
TextForm.MemoT.Lines.Add(lLabelStr+ lLabelStr20[lInc] +kTextSep+ inttostr(lHisto[lInc])+kTextSep+floattostr( lHisto[lInc]/lRegionVol[lInc])) ;
2597
2525
end; //for each row
2648
2576
lStr := 'Overlay #'+inttostr(lOverlayNum);
2649
2577
if not lShowFilename then begin
2650
TextForm.Memo1.Lines.Add(lStr+' '+gMRIcroOverlay[lOverlayNum].HdrFileName);
2578
TextForm.MemoT.Lines.Add(lStr+' '+gMRIcroOverlay[lOverlayNum].HdrFileName);
2652
2580
//TextForm.Memo1.Lines.Add('CoM');
2653
2581
if CenterOfMass (lOverlayNum, lCenterOfMass[1],lCenterOfMass[2],lCenterOfMass[3]) > 0 then
2654
TextForm.Memo1.Lines.Add(' '+lLabelStr+' Center of mass XYZ '+RealToStr(lCenterOfMass[1],2)+'x'+RealToStr(lCenterOfMass[2],2)+'x'+RealToStr(lCenterOfMass[3],2));
2582
TextForm.MemoT.Lines.Add(' '+lLabelStr+' Center of mass XYZ '+RealToStr(lCenterOfMass[1],2)+'x'+RealToStr(lCenterOfMass[2],2)+'x'+RealToStr(lCenterOfMass[3],2));
2655
2583
for lInc := 1 to 3 do begin
2656
2584
if lROIVol[lInc] > 1 then begin
2657
2585
lSD := (lROISumSqr[lInc] - ((Sqr(lROISum[lInc]))/lROIVol[lInc]));
2681
2609
2: lStr := 'VOI <>0 ';
2682
2610
else lStr := 'VOI ';
2684
lStr := lStr+' n=min/mean/max=SD: '+inttostr(round(lROIVol[lInc]))+'['+RealToStr(lCC,2)+'cc]='+RealToStr(lROIMin[lInc],4)+'/'+realToStr(lROIMean,4)+'/'+realToStr(lROIMax[lInc],4)+'='+realtostr(lSD,4);
2685
TextForm.Memo1.Lines.Add(lLabelStr+ lStr);
2612
lStr := lStr+' nvox(cc)=min/mean/max=SD: '+inttostr(round(lROIVol[lInc]))+kTextSep+RealToStr(lCC,2)+kTextSep+'='+kTextSep+RealToStr(lROIMin[lInc],4)+kTextSep+realToStr(lROIMean,4)+kTextSep+realToStr(lROIMax[lInc],4)+kTextSep+'='+kTextSep+realtostr(lSD,4);
2613
TextForm.MemoT.Lines.Add(lLabelStr+ lStr);
2687
2615
//June07 if (gMRIcroOverlay[kBGOverlayNum].UsesCustomPalette) or (lShowFilename) then
2688
2616
DescribeVOIonLabels(lOverlayNum,lShowfilename);
2689
TextForm.Memo1.Lines.Add('');
2617
TextForm.MemoT.Lines.Add('');
2690
2618
ImgForm.SaveDialog1.Filename := ExtractFileDirWithPathDelim(gMRIcroOverlay[lOverlayNum].HdrFileName)+'desc.csv';
3926
3855
lLabelStr := ' ';
3927
3856
if lVOI then //intensity min/max position are not important
3928
TextForm.Memo1.Lines.add(lLabelStr+'Area,N>0,%N>0')
3857
TextForm.MemoT.Lines.add(lLabelStr+'Area'+kTextSep+'N>0'+kTextSep+'%N>0')
3930
TextForm.Memo1.Lines.add(lLabelStr+'Area,N>0,%N>0,Sum>0,Mean>0,Max,MaxX,MaxY,MaxZ');
3859
TextForm.MemoT.Lines.add(lLabelStr+'Area'+kTextSep+'N>0'+kTextSep+'%N>0'+kTextSep+'Sum>0'+kTextSep+'Mean>0'+kTextSep+'Max'+kTextSep+'MaxX'+kTextSep+'MaxY'+kTextSep+'MaxZ');
3931
3860
//next initialize
3932
3861
if lShowFilename then
3933
3862
lLabelStr := gMRIcroOverlay[lOverlayNum].HdrFileName+','
3975
3904
lLocalMax[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalMax[lInc]);
3976
3905
lLocalSum[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalSum[lInc]);
3977
3906
ImgPosToMM(lLocalMaxPos[lInc], lXmm,lYmm,lZmm);
3978
TextForm.Memo1.Lines.Add(lLabelStr+ lLabelStr20[lInc] + ', ' + inttostr(lHisto[lInc])+','+floattostr( lHisto[lInc]/lRegionVol[lInc])
3979
+','+floattostr( lLocalSum[lInc])+','+floattostr( lLocalSum[lInc]/lRegionVol[lInc]) //Sum>0, mean>0
3980
+', ' + floattostr(lLocalMax[lInc])+','+floattostr(lXmm)+','+floattostr(lYmm)+','+floattostr(lZmm) );
3907
TextForm.MemoT.Lines.Add(lLabelStr+ lLabelStr20[lInc] +kTextSep+ inttostr(lHisto[lInc])+kTextSep+floattostr( lHisto[lInc]/lRegionVol[lInc])
3908
+kTextSep+floattostr( lLocalSum[lInc])+kTextSep+floattostr( lLocalSum[lInc]/lRegionVol[lInc]) //Sum>0, mean>0
3909
+kTextSep + floattostr(lLocalMax[lInc])+kTextSep+floattostr(lXmm)+kTextSep+floattostr(lYmm)+kTextSep+floattostr(lZmm) );
3981
3910
end else if (lHisto[lInc] > 0) {necessarily also and (lRegionVol[lInc] > 0)} then
3982
TextForm.Memo1.Lines.Add(lLabelStr+ lLabelStr20[lInc] + ', ' + inttostr(lHisto[lInc])+','+floattostr( lHisto[lInc]/lRegionVol[lInc])) ;
3911
TextForm.MemoT.Lines.Add(lLabelStr+ lLabelStr20[lInc] + kTextSep+ inttostr(lHisto[lInc])+kTextSep+floattostr( lHisto[lInc]/lRegionVol[lInc])) ;
3983
3912
end; //for each row
4054
3983
end; //for each voxel
4055
3984
//next - compute StDev
4056
3985
//compute descriptives for each set of values
4057
TextForm.Memo1.Lines.Add('Overlay '+gMRIcroOverlay[lOverlayNum].HdrFileName);
3986
TextForm.MemoT.Lines.Add('Overlay '+gMRIcroOverlay[lOverlayNum].HdrFileName);
4058
3987
if CenterOfMass (lOverlayNum, lCenterOfMass[1],lCenterOfMass[2],lCenterOfMass[3]) > 0 then
4059
TextForm.Memo1.Lines.Add(' Center of mass XYZ '+RealToStr(lCenterOfMass[1],2)+'x'+RealToStr(lCenterOfMass[2],2)+'x'+RealToStr(lCenterOfMass[3],2));
3988
TextForm.MemoT.Lines.Add(' Center of mass XYZ '+RealToStr(lCenterOfMass[1],2)+'x'+RealToStr(lCenterOfMass[2],2)+'x'+RealToStr(lCenterOfMass[3],2));
4060
3989
for lInc := 1 to 3 do begin
4061
3990
if lROIVol[lInc] > 1 then begin
4062
3991
lSD := (lROISumSqr[lInc] - ((Sqr(lROISum[lInc]))/lROIVol[lInc]));
4082
4011
2: lStr := 'VOI <>0 ';
4083
4012
else lStr := 'VOI ';
4085
lStr := lStr+' n=min/mean/max=SD: '+inttostr(round(lROIVol[lInc]))+'['+RealToStr(lCC,2)+'cc]='+RealToStr(lROIMin[lInc],4)+'/'+realToStr(lROIMean,4)+'/'+realToStr(lROIMax[lInc],4)+'='+realtostr(lSD,4);
4086
TextForm.Memo1.Lines.Add(lStr);
4014
lStr := lStr+' nvox(cc)=min/mean/max=SD: '+inttostr(round(lROIVol[lInc]))+kTextSep+RealToStr(lCC,2)+kTextSep+'='+RealToStr(lROIMin[lInc],4)+kTextSep+realToStr(lROIMean,4)+kTextSep+realToStr(lROIMax[lInc],4)+kTextSep+'='+kTextSep+realtostr(lSD,4);
4015
TextForm.MemoT.Lines.Add(lStr);
4088
4017
if gMRIcroOverlay[kBGOverlayNum].UsesCustomPalette then
4089
4018
DescribeVOIonLabels(lOverlayNum);
4090
TextForm.Memo1.Lines.Add('');
4019
TextForm.MemoT.Lines.Add('');
4091
4020
end; //overlaynum loaded
4092
4021
end; //for each overlay