{This macro set includes macros from "confocal_macros" for the import of BioRad .pic files. The compensation macros were written by Michael Binks to use code written by Richard Herd in "NIH-Image_Scatter" available on the NIH-Image ftp server.} var i,n,p,o,l,w,h,s,x,y,m,t:integer; angle,corrfactor:real; name:string; macro 'Import Biorad MRC 600 Z Series [Z]'; { Imports a Z series(multiple images per file) from a Biorad MRC 600 confocal microscope. The width, height and number of images are extracted from the first 3 16-bit word in the 76 byte header and the file name is extracted from bytes 18-23 of the header. Note that the Undo and Clipboard buffers must be set to at least 384K to work with the typical 768x512 Biorad images. } var width,height,nImages,offset,hdrsize,i,start,picsize:integer; begin RequiresVersion(1.50); width:=512; height:=1; offset:=0; SetImport('8-bit'); SetCustom(width,height,offset); Import(''); {Read header} width:=GetPixel(0,0)+GetPixel(1,0)*256; height:=GetPixel(2,0)+GetPixel(3,0)*256; nImages:=GetPixel(4,0)+GetPixel(5,0)*256; Dispose; hdrsize:= 76; picsize:=width*height; if (width<128) or (width>2048) or (height<128) or (height>2048) or (nImages<1) or (nImages>256) then begin PutMessage('This does not seem to be a Biorad MRC 600 Z Series file.'); exit; end; start:=1; offset:=HdrSize+(start-1)*PicSize; SetImport('8-bit; Invert'); SetCustom(width,height,offset,nimages); Import(''); for i:=1 to nSlices do begin SelectSlice(i); { Invert;} ChangeValues(0,0,1); ChangeValues(255,255,254); end; {Add SetScale and SliceSpacing Calls at this point for calibrating mag factor and Z-series spacing. } end; macro 'Merge Split BioRAD [S]'; {Makes a macro that color merges a split screen BioRAD image, as a merged color image. This macro has been altered from that in "confocal_macros" so that the Right hand image becomes the Red slice (which suits our system).} var p,w,h,rgb,l: integer name1,name: string; begin p:= PidNumber; SelectPic(p); GetPicSize(w,h); name1:=WindowTitle; l:=length(name1); Delete(name1,(l-2),3); MakeRoi(0,0,w/2,h); Copy; SetNewSize(w/2,h); MakeNewStack(name1,'RGB'); {Change this to read the name of the original file "Original Name", then name the new stack as "Original Name - Unsplit&Merge". } rgb:=PicNumber; SelectPic(rgb); AddSlice; Paste; SetBackground(255); AddSlice; SelectPic(p); MakeRoi(w/2,0,w/2,h); Copy; SelectPic(rgb); SelectSlice(1); Paste; SetBackGround (255); RGBToIndexed('System LUT Dither'); ChoosePic(p); Dispose; SelectWindow('Indexed Color'); Dispose; end; macro '(-' begin end; {The following procedures are used by the Compensation macros} procedure CheckForStack; begin if nSlices=0 then begin PutMessage('This window is not a stack'); exit; end; end; procedure CheckForRGB; begin if (nSlices>3) or (nSlices<3) then begin PutMessage('This window is not an RGB stack'); exit; end; end; procedure InvertStack; begin for i:= 1 to nSlices do begin ChooseSlice(i); Invert; end; SelectSlice(1); end; procedure CompensateStack; begin {Image that is the source of cross-over is selected and modified to represent the proportion of the original which is present in the other channel} GetPicSize(w,h); SelectSlice(y); Duplicate(WindowTitle); SetPicName('Correction'); p:=PicNumber; MultiplyByConstant(corrfactor); {New RGB stack is made with compensated images (the above modified image is subtracted from the other channel)} SetNewSize(w,h); MakeNewStack(name,'comp');AddSlice;AddSlice; o:=PidNumber; ChoosePic(n); ChooseSlice(x);SelectAll;Copy; ChoosePic(o);ChooseSlice(x);Paste; ImageMath('sub',o,p,1,0,o); ChoosePic(p);Dispose; ChoosePic(n);ChooseSlice(y);SelectAll;Copy; ChoosePic(o);ChooseSlice(y);Paste; end; procedure MarkAxes; begin MoveTo(20,236); writeln('(Green)'); MoveTo(290,392); writeln('(Red)'); end; procedure FirstScatter; {Makes scatter plot of stack before compensation} begin name:=WindowTitle;n:=PidNumber; GetPicSize(w,h); l:=length(name); Delete(name,(l-2),3); InvertStack; UserCode('TwoSliceScatter',1,2,0); SelectAll;Copy;Dispose; SetNewSize(456,456); MakeNewStack(name,'scatter');Paste; {MoveWindow(600,50);}{Suitable for 20" monitor at high resolution} s:=PidNumber; MoveTo(100,50); writeln('Normal'); MarkAxes; SetDensitySlice(1,1); end; procedure SecondScatter; {Makes scatter plot of stack after compensation} begin UserCode('TwoSliceScatter',1,2,0); SelectAll;Copy;Dispose; ChoosePic(s);AddSlice;Paste; SetDensitySlice(1,1); MoveTo(100,50); writeln('Compensation = ',(corrfactor*100):4:2,' %'); MarkAxes; end; procedure MeasureAngle; {Measures the angle of displacement of the dot plot from the horizontal} begin SetOptions('Angle Area'); IgnoreParticlesTouchingEdge(true); IncludeInteriorHoles(true); LabelParticles(false); OutlineParticles(true); SetParticleSize(1000,99999); AnalyzeParticles;Undo; if rCount>1 then begin for i:=1 to rCount do begin if rArea[i]>m then begin m:=rArea[i]; t:=i; end; end; end; end; macro 'Add Slice to Stack [A]'; begin CheckForStack; SelectSlice(nSlices); AddSlice; end; macro 'Invert Stack [I]'; begin InvertStack; end; macro 'RGB to 8-bit colour [R]'; begin CheckForStack; CheckForRGB; name:=WindowTitle; SetBackGround (255); RGBToIndexed('System LUT Dither'); SetPicName(name,'.8bCol'); end; macro '(-' begin end; macro 'Compensation Macro Info [F1]'; begin NewTextWindow('Compensation Macro Info'); SetFont('Helvetica'); SetFontSize(12); writeln('These NIH-Image macros are intended for use with 2 colour fluoresence images acquired from a confocal microscope. They make use of User.p code written by Richard Herd in "NIH-Image_Scatter" which he has made available on the NIH-Image ftp server.'); writeln(''); writeln('Their purpose is to simplify post-acquisition compensation for "bleed through" of fluorescent emission between red and green detector channels. For quantitative co-localisation studies such a correction is important to obtain objective results.'); writeln(''); writeln('A linear relationship between fluorescence intensity and cross-over between detector channels is assumed (and in our experience is correct).'); writeln(''); writeln('This is calculated using a scatter plot of pixel values in green and red images in an RGB stack from a single colour fluorescence control. The calculated compensation is then applied on a pixel by pixel basis to images of two colour samples.'); writeln(''); writeln('Instructions:'); writeln(''); writeln('1. Load macros into NIH-Image_Scatter.'); writeln('2. Import confocal images and make RGB stack (leave so that background is black).'); writeln('3. Select single colour control image and use items [1] or [3] from Special menu (Press [1] or [3] on keyboard)'); writeln('4. Select dual colour image and use items [2] or [4] from Special menu (Press [2] or [4] on keyboard)'); writeln(''); writeln('"Green -> Red" ([1] and [2]) will compensate for "bleed through" from the green to the red channel and vice versa.'); writeln(''); writeln('Please send any comments or criticisms to m.binks@ucl.ac.uk'); end; macro '(-' begin end; macro 'Measure Green -> Red Control [1]'; begin corrfactor:=0;angle:=0;w:=0;h:=0; x:=1;y:=2;t:=1; CheckForStack; CheckForRGB; FirstScatter; MeasureAngle; angle:=(90-rAngle[t])/57.295779513;{Calculates displacement from vertical in radians} corrfactor:=sin(angle)/cos(angle);{Calculates ratio of 2 sides of triangle (b/a)} ChoosePic(n); CompensateStack; SecondScatter; ShowMessage('Angle = ',(90-rAngle[1]),' degrees','\','Compensation factor = ',corrfactor); end; macro 'Compensate Green -> Red Sample [2]'; begin x:=1;y:=2; CheckForStack; CheckForRGB; corrfactor:=GetNumber('Correction Factor = ',corrfactor,4); FirstScatter; ChoosePic(n); CompensateStack; SecondScatter; end; macro '(-' begin end; macro 'Measure Red -> Green Control [3]'; begin corrfactor:=0;angle:=0;w:=0;h:=0; x:=2;y:=1;t:=1; CheckForStack; CheckForRGB; FirstScatter; MeasureAngle; angle:=(rAngle[t])/57.295779513;{Calculates displacement from horizontal in radians} corrfactor:=sin(angle)/cos(angle); ChoosePic(n); CompensateStack; SecondScatter; ShowMessage('Angle = ',rAngle[1],' degrees','\','Compensation factor = ',corrfactor); end; macro 'Compensate Red -> Green Sample [4]'; begin x:=2;y:=1; CheckForStack; CheckForRGB; corrfactor:=GetNumber('Correction Factor = ',corrfactor,4); FirstScatter; ChoosePic(n); CompensateStack; SecondScatter; end;