{Cavalieri Macros, Glen MacDonald, Virginia Merrill Bloedel Hearing Research Center, Univ. Washington, (206) 616-4156, glenmac@u.washington.edu. March 16, 1993 rev April 14, 1997. Thanks to Ed Huff, Jay Charleston and Wayne Rasband for their suggestions, John Russ for rotating the cycloids and other nice touches. These macros scale vertically according to the aspect ratio. Set the aspect ratio to 1.0 if working with images that have been corrected for non-square pixels. The usual disclaimers apply.} var {global variables for grids} {User parameters} FrameArea,Geometric,TileArea,Pelpermicron,PAspectratio,Bdy,tileratio:real; limit,color,lthick,startinterval,spotdia:integer; {Computed vars} picheight,picwidth,FrameSide,dia,pi:real; width,height,xr,yr,x,y,TileSide,TileArm,TileSize,randomvalue:real; linesv,linesh:integer; units:string; {flags} RandomMacroCalled,ifpic, BdyMacroCalled,expon:integer; DidScale:boolean; var {global variables unique for recording point counts} N3,N2,N1:real;{real type allows decimal descriptors} pointCount,Count1,Count2,Count3,Count4,ClickCount:integer; didcount:boolean; var {random number variables} randomvalue,rlimit,r,HowMany:integer; Procedure CheckArea; begin GetScale(pelpermicron,units,PAspectratio); if (TileArea = 0) and (didscale=0) then begin TileSide:=(40*pelpermicron); TileArea:= TileSide* TileSide; end else begin TileSide:=sqrt(TileArea)*pelpermicron; end; TileArm:=5; Tileratio:=TileSide/PAspectratio; end; Procedure Checkforpic; {Called with Set Scale Macro. Checks to see if the user has set the scale from the Analyze menu, or has visited the Set Scale macro. } begin RequiresVersion(1.58); ifpic:=npics; if (ifpic = 0) then begin putmessage ('You must have an image displayed.'); exit; end else begin CheckArea; end; end; Macro 'Set Scale [S]'; begin Checkforpic; DidScale:=true; Pelpermicron:=GetNumber('How many pixels per micron?',Pelpermicron,2); PAspectRatio:=GetNumber('Pixel aspect ratio (width/height):',PAspectratio,4); SetScale(pelpermicron,'µm',PAspectratio); end; Macro 'Set Tile Area [T]'; begin CheckArea; TileArea:=GetNumber(concat('Area of each tile, square ',units,'s:'), TileArea,2); CheckArea; end; macro 'More template settings below...'; begin end; Procedure IfSpotDia; begin if (spotdia = 0) then spotdia:=3; end; {this section of the macro relates to sample identification and recording counts as the user clicks the cursor on template intersections} macro '(---'; begin end; Procedure WaitForButton; begin repeat until Button; repeat until not button; end; macro 'Identify Sample [I]'; {User enters 3 identifiers for the sample,macro resets the counters and number of colors for markers} {Press 1, then start clicking on objects, intersections or points, click up on the menu bar to terminate counts for this category. then either press 2,3 or 4 for another category or press 'D'} begin RequiresVersion(1.58); GetPicSize(width,height); SetOptions('Area,Mean,Std.Dev,X-YCenter,Major,Minor,User1,User2'); SetPalette('',6); SetPrecision(2,10); SetMajorLabel('Count1'); SetMinorLabel('Count2'); SetUser1Label('Count3'); SetUser2Label('Count4'); N1:=GetNumber('Slide Number:',N1,3);{you could delete N1, N2, N3 if they annoy users, if you do, also delete "Area, Mean, St. Dev" from SetOptions, and the :=Nn lines in the Done Macro} N2:=GetNumber('Section:',N2,1); N3:=GetNumber('Other Identifier:',N3,0); SetCounter(rCount+1);{store the counter} ClickCount:=rCount; Count1:=0; Count2:=0; Count3:=0; Count4:=0; end; Procedure CountPoints; begin SetCursor('cross'); WaitForButton; getMouse(x,y); Measure; PointCount:=PointCount+1; MakeOvalRoi(x,y,spotdia,spotdia); Fill; end; macro 'Count First Label [1]'; begin IfSpotDia; killroi;{get around the NotInBounds error} SetForegroundColor(2); PointCount:=0; getMouse(x,y); repeat while (x>0) and (y>0) do begin CountPoints; end; if (x<0) or (y<0) then begin Count1:=PointCount-1;{delete terminating count} UpdateResults; SetCounter(clickCount); end; didcount:=true; beep; exit; end; macro 'Count Second Label [2]'; begin IfSpotDia; killroi; SetForegroundColor(3); PointCount:=0; getMouse(x,y); repeat while (x>0) and (y>0) do begin CountPoints; end; if (x<0) or (y<0) then begin Count2:=PointCount-1;{delete terminating count} UpdateResults; SetCounter(clickCount); end; beep; didcount:=true; exit; end; macro 'Count Third Label [3]'; begin IfSpotDia; killroi; SetForegroundColor(4); PointCount:=0; getMouse(x,y); repeat while (x>0) and (y>0) do begin CountPoints; end; if (x<0) or (y<0) then begin Count3:=PointCount-1;{delete terminating count} UpdateResults; SetCounter(clickCount); end; beep; didcount:=true; exit; end; macro 'Count Fourth Label [4]'; begin IfSpotDia; killroi; SetForegroundColor(5); PointCount:=0; getMouse(x,y); repeat while (x>0) and (y>0) do begin CountPoints; end; if (x<0) or (y<0) then begin Count4:=PointCount-1;{delete terminating count} UpdateResults; SetCounter(clickCount); end; beep; didcount:=true; exit; end; macro 'Done with Counts [D]'; begin if didcount=false then begin putmessage('Either no category has been counted, or counts have not been terminated by clicking outside of the image.'); exit; end; SetForegroundColor(254); rX[rCount]:= TileSize; rY[rCount]:=expon; rMajor[rCount]:=Count1; rMinor[rCount]:=Count2; rUser1[rCount]:=Count3; rUser2[rCount]:=Count4; rArea[rCount]:=N1; rStdDev[rCount]:=N3; rMean[rCount]:=N2; UpdateResults; SetCounter(clickCount); end; macro '(---'; begin end; Procedure ColorLineError; begin if (lThick = 0) then lThick:=1; SetLineWidth(lThick); if (color = 0) then color:=1; SetForegroundColor(color); end; Procedure RandomStart; begin Checkforpic; if (RandomMacroCalled = 0) then startinterval:=1; if (BdyMacroCalled = 0) then Bdy:=10; xr:=(random*(startinterval*TileRatio))+Bdy; yr:=(random*(startinterval*TileSide))+(Bdy*PAspectRatio); end; Procedure Superimpose; {if control key is held down then other tiles can be overlaid with the same coordinates for the origin, while attributes such as tile area, line color, etc. may be changed before invoking the next template. Must be used with "menually" selected macros. } begin if KeyDown('control') then beep else RandomStart; end; Procedure WithInImage; {How many rows and columns are there?} begin Checkforpic; GetPicSize(width,height); linesv:= trunc((width-bdy-TileSide)/TileSide); {number of columns} linesh:= trunc((height-bdy-TileSide)/TileRatio);{number of rows} end; Procedure WritePoints; begin SetFont('Geneva'); SetFontSize(10); MoveTo (2,height-6); Write('Total Points = ',k:3); Moveto (125,height-6); Write('Point Area = ',TileArea:10:2,' sq.',units); Moveto(340, Height-6); Write('Total Area = ',(k*tileArea):10:2,' sq.',units); expon:=2; TileSize:=TileArea; end; Procedure WriteCycloids; var TileLength:real; begin TileLength:=sqrt(tileArea); SetFont('Geneva'); SetFontSize(10); MoveTo (2,height-18); Write('Total Lines =',k:3); Moveto (125,height-18); Write('Line Length =',TileLength:10:2,' ',units); Moveto (340,height-18); Write('Total Length =',(k*TileLength):10:2,' ',units); expon:=1; TileSize:=sqrt(TileArea); end; Macro 'Point Count Square Grid [P]'; var i,j,k:integer; xoff,yoff:real; begin ColorLineError; Superimpose; WithInImage; for i:=0 to linesv do begin {make verticals} xoff:=xr+(i*TileSide); MoveTo(xoff,yr); LineTo(xoff,yr+(linesh*Tileratio)); end; for j:=0 to linesh do begin {make horizontal lines} yoff:=yr+(j*Tileratio); MoveTo(xr,yoff); Lineto(xr+(linesv*Tileside),yOff); end; killroi; k:=(linesv*linesh); WritePoints; end; macro '(---'; begin end; Macro 'Option key staggers these...'; begin end; Procedure PointCountCrosses; begin for j:=0 to linesv do begin XOff:= Xr + (j * TileSide); for i:=0 to linesh do begin YOff:= Yr + (i*Tileratio); MoveTo(XOff - tileArm,YOff); LineTo(XOff-1,YOff); MoveTo(XOff + tileArm,YOff); LineTo(XOff+1,YOff); MoveTo(XOff,YOff + tileArm); LineTo(XOff,YOff+1); MoveTo(XOff,YOff-tileArm); LineTo(XOff,YOff-1); k:=k+1; end; end; end; Procedure StaggeredCrosses; begin YrOdd:=Yr+(TileRatio/2); for j:=0 to linesv do begin XOff:= Xr + (j * TileSide); if odd(j) then YrT := YrOdd else YrT:= Yr; for i:=0 to linesh do begin YOff:= YrT + (i * TileRatio); MoveTo(XOff - tileArm,YOff); LineTo(XOff-1,YOff); MoveTo(XOff + tileArm,YOff); LineTo(XOff+1,YOff); MoveTo(XOff,YOff + tileArm); LineTo(XOff,YOff+1); MoveTo(XOff,YOff-tileArm); LineTo(XOff,YOff-1); k:=k+1; end; i:=0; end; KillRoi; end; Macro 'Point Count Crosses [X]'; Var i,k,j:integer; YrOdd,YrT,XOff,YOff:real; begin Superimpose; ColorLineError; WithInImage; k:=0; if keydown('option') then StaggeredCrosses else PointCountCrosses; WritePoints; end; Procedure Pointcountspots; begin for j:=0 to linesv do begin XOff:= Xr + (j *TileSide); for i:=0 to linesh do begin YOff:= Yr + (i* TileRatio); MakeOvalRoi( XOff,YOff,spotdia,spotdia); Fill; k:=k+1; end; end; killroi; WritePoints; end; Procedure StaggeredSpots; begin YrOdd:=Yr+(TileRatio/2); for j:=0 to linesv do begin XOff:= Xr + (j * TileSide); if odd(j) then YrT := YrOdd else YrT:= Yr; for i:=0 to linesh do begin YOff:= YrT+ (i*TileRatio); MakeOvalRoi( XOff,YOff,spotdia,spotdia); Fill; k:=k+1; end; end; killroi; WritePoints; end; Macro 'Point Count Spots [O]'; var i,k,j:integer; YrOdd,YrT,XOff,Yoff:real; begin Superimpose; IfSpotDia; ColorLineError; WithInImage; k:=0; if keydown('option') then StaggeredSpots else PointCountSpots; end; Procedure LengthDensity; begin while j < linesv do begin for i:=0 to linesh do begin YOff:= Yr + (i*TileRatio); MoveTo(XOff - tileArm,YOff); {left arm} LineTo(XOff-1,YOff); MoveTo(XOff,YOff + tileArm); LineTo(XOff,YOff+1); MoveTo(XOff,YOff-tileArm); LineTo(XOff,YOff-1); MoveTo(XOff +TileSide,YOff); {length estimator} LineTo(XOff+1,YOff); MoveTo(XOff +TileSide+1,YOff + tileArm); LineTo(XOff +TileSide+1,YOff+1); MoveTo(XOff +TileSide+1,YOff-tileArm); LineTo(XOff +TileSide+1,YOff-1); k:=k+1; end; j:=j+2; XOff:= Xr + (j * TileSide); end; end; Procedure StaggeredLength; begin if Yr >(TileRatio/2)+Bdy then YrOdd:=Yr-(TileRatio/2) else YrOdd:=Yr+(TileRatio/2); for j:=0 to linesv do begin if odd(j) then YrT := YrOdd else YrT:= Yr; for i:=0 to linesh do begin XOff:= Xr +(j * tileSide); YOff:= YrT + (i*TileRatio); MoveTo(XOff - tileArm,YOff); {left arm} LineTo(XOff-1,YOff); MoveTo(XOff,YOff + tileArm);{top arm} LineTo(XOff,YOff+1); MoveTo(XOff,YOff-tileArm);{lower arm} LineTo(XOff,YOff-1); MoveTo(XOff +TileSide,YOff); {length estimator} LineTo(XOff+1,YOff); MoveTo(XOff +TileSide+1,YOff + tileArm); LineTo(XOff +TileSide+1,YOff+1); MoveTo(XOff +TileSide+1,YOff-tileArm); LineTo(XOff +TileSide+1,YOff-1); k:=k+1; {counter} end; end; end; Macro 'Length Density [L]'; var i,j,k,YrOdd,YrT:integer; XOff,YOff,Area:real; begin ColorLineError; WithInImage; Superimpose; j:=0; k:=0; XOff:= Xr; if keydown('option') then StaggeredLength else LengthDensity; WriteCycloids; end; Procedure VertDensity; begin while i < linesh do begin for j:=0 to linesv do begin XOff:= Xr + (j*TileSide); MoveTo(XOff - tileArm,YOff); {left arm} LineTo(XOff-1,YOff); MoveTo(XOff,YOff - tileArm);{top arm} LineTo(XOff,YOff-1); MoveTo(XOff+tilearm,YOff);{right arm} LineTo(XOff+1,YOff); MoveTo(XOff,YOff+Tileratio-1); {length estimator} LineTo(XOff,YOff+1); MoveTo(XOff - tileArm ,YOff+Tileratio); {left arm} LineTo(XOff-1,YOff+Tileratio); MoveTo(XOff +tilearm,YOff+Tileratio);{right arm} LineTo(XOff+1,YOff+Tileratio); k:=k+1; end; i:=i+2; YOff:= Yr + (i * Tileratio); end; end; Procedure SVertLength; begin if Xr >(TileSide/2)+Bdy then XrOdd:=Xr-TileSide/2 else XrOdd:=Xr+TileSide/2; for i:=0 to linesh-1 do begin if odd(i) then XrT:= XrOdd else XrT:= Xr; for j:=0 to linesv-1 do begin YOff:= Yr+ (i *Tileratio); XOff:= XrT + (j*TileSide); MoveTo(XOff - tileArm,YOff); {left arm} LineTo(XOff-1,YOff); MoveTo(XOff,YOff - tileArm);{top arm} LineTo(XOff,YOff-1); MoveTo(XOff+tilearm,YOff);{right arm} LineTo(XOff+1,YOff); MoveTo(XOff,YOff+ Tileratio-1); {length estimator} LineTo(XOff,YOff+1); MoveTo(XOff - tileArm ,YOff+ Tileratio); {left arm} LineTo(XOff-1,YOff+ Tileratio); MoveTo(XOff +tilearm,YOff+ Tileratio);{right arm} LineTo(XOff+1,YOff+Tileratio); k:=k+1; end; end; end; Macro 'Vertical Density [K]'; var i,j,k,YrOdd,XrT, XrOdd:integer; XOff,YOff,Area:real; begin ColorLineError; WithInImage; Superimpose; i:=0; k:=0; YOff:= Yr; if keydown('option') then SVertLength else VertDensity; WriteCycloids; end; Procedure RotateCycloids; begin IF h =1 THEN {normal cycloid} BEGIN cx:=xoff+dx; {dx:=(Tileside-base)/2;} cy:=yoff-dy; {dy:=Tileratio/4;} MoveTo(cx,cy); For p := 1 to TileSide DO BEGIN theta:=(pi/Tileside) *p; xstep:=dy*(theta-sin(theta)); ystep:=dy*(1.0-cos(theta)); Lineto (cx+xstep,cy-ystep); END; END; {for cycloid} IF h = 2 THEN {turned 90 deg. CW} BEGIN cx:=xoff+(TileSide/4); cy:=yoff-((tileratio-base)/2)-base; MoveTo (cx,cy); For p := 1 to Tileside DO BEGIN theta:=(pi/Tileside) *p; xstep:=dy*(1.0-cos(theta)); ystep:=dy*(theta-sin(theta)); Lineto (cx+xstep,cy+ystep); END; END; IF h =3 THEN {turned 180 deg CW} {NOT Corrected for Aspect Ratio} BEGIN cx:=xoff+dx+base; cy:=yoff-3*dy; MoveTo (cx,cy); For p := 1 to Tileside DO BEGIN theta:=(pi/Tileside) *p; xstep:=dy*(theta-sin(theta)); ystep:=dy*(1.0-cos(theta)); Lineto (cx-xstep,cy+ystep); END; END; IF h =4 THEN {NOT Corrected for Aspect Ratio} BEGIN cx:=xoff+3*dy; cy:=yoff-dx; MoveTo (cx,cy); For p := 1 to Tileside DO BEGIN theta:=(pi/Tileside) *p; xstep:=dy*(1.0-cos(theta)); ystep:=dy*(theta-sin(theta)); Lineto (cx-xstep,cy-ystep); END; END; end; {RandomCycloids} Procedure HorizCycloids; Begin {cycloids are pi*Tileside/4 wide x Tileside/2 high, length Tileside spaced in a regular grid of TileSide square} YrT:=Yr; for j:=0 to linesv-1 do begin; XOff:=Xr+(j*TileSide); for i:=1 to linesh do begin h:=1; YOff:= YrT+ (i*TileRatio); RotateCycloids; k:=k+1; END; {for i} END; {for j} WriteCycloids; END; Procedure SHorizCycloids; Begin {cycloids are pi*Tileside/4 wide x Tileside/2 high, length Tileside spaced in a staggered grid of TileSide square (centered in the Point Count Grid)} ColorLineError; linesvert:=linesv-1; for j:=0 to linesvert do begin {make columns} XOff:= Xr + (j *Tileside); if odd(j) then begin {YrT controls offset for staggering grids} YrT:=Yr-2*dy; lineshorz:=linesh; end else begin YrT:= Yr; lineshorz:=linesh; end; for i:=1 to lineshorz do begin {make rows} h:=1; YOff:= YrT+ (i*TileRatio); RotateCycloids; k:=k+1; END; {for i} END; {for j} WriteCycloids; END; Macro 'Horizontal Cycloids [C]'; Var h,i,j,k,p,limit,lineshorz,linesvert:integer; YrT,pi,thetax,theta,dx,dy,xoff,yoff,base,cx,cy,xstep,ystep:real; begin WithInImage; Superimpose; k:=0; pi:=3.1415927; dy:=Tileratio/4; base:=pi*dy; dx:=(Tileside-base)/2; if keydown('option') then SHorizCycloids else HorizCycloids; end; Procedure VertCycloids; Begin {cycloids are pi*Tileside/4 _high_ x Tileside/2 _wide_, length = Tileside, spaced in a grid of TileSide square tiles (centered in the Point Count Grid)} YrT:=Yr; for j:=0 to linesv-1 do begin; XOff:=Xr+(j*TileSide); for i:=1 to linesh do begin YOff:= YrT+ (i*Tileratio); RotateCycloids; k:=k+1; END; {for i} END; {for j} WriteCycloids; END; Procedure SVertCycloids; begin {cycloids are pi*Tileside/4 wide x Tileside/2 high, length = Tileside spaced in a grid of TileSide square tiles and randomly oriented in 90 degree increments} j:=0; for j:=0 to linesv-1 do begin {make columns} XOff:= Xr + (j *TileSide); if odd(j) then YrT:=Yr+2*dy else YrT:=Yr;{YrT controls offset for staggering grids} for i:=1 to linesh do begin {make rows} YOff:= YrT+ (i*Tileratio); RotateCycloids; k:=k+1; END; {for i} END; {for j} WriteCycloids; END; Macro 'Vertical Cycloids [V]'; Var h,i,j,k,p,limit:integer; YrT,pi,theta,dx,dy,xoff,yoff,base,cx,cy,xstep,ystep:real; begin ColorLineError; WithInImage; Superimpose; pi:=3.1415927; dy:=Tileratio/4; base:=dy*pi; dx:=(TileSide - base)/2; h:=2; k:=0; if keydown('option') then SVertCycloids else VertCycloids; end; macro '(---'; begin end; Macro 'Set Counting Frame Area'; begin RequiresVersion(1.58); Checkforpic; if (FrameArea = 0) then FrameArea:=sqr(300/pelpermicron); FrameArea:=GetNumber(concat('Counting Frame Area, square ',units,'s:'), FrameArea,2); FrameSide:=sqrt(FrameArea); end; end; Macro 'Counting Frame [F]'; var xf1,yf1, voffset,hoffset, fleft,ftop,fwidth,fheight,Zone:real; begin RequiresVersion(1.58); GetPicSize(picwidth,picheight); ColorLineError; GetScale(pelpermicron,units,PAspectratio); if (FrameSide = 0) then begin PutMessage('Use the macro "Set Counting Frame Area" to choose a frame area.'); exit; end; voffset:=(PicHeight-(Frameside*Paspectratio))/2; hoffset:=(PicWidth-Frameside)/2; xf1:=hoffset; yf1:=picHeight-(Frameside+voffset); MakeRoi(xf1,yf1,FrameSide,Frameside/Paspectratio); measure; Geometric:=rArea[rCount]; Getroi(fleft,ftop,fwidth,fheight); expon:=2; DrawBoundary; KillRoi; Zone:=(FrameSide/4); Moveto(fleft,ftop); MakeLineRoi(fleft,ftop,fleft,ftop-zone); Fill; MoveRoi(fwidth-lthick,(fheight+zone)); fill; Killroi; SetCounter(clickCount); SetFont('Geneva'); SetFontSize(10); Moveto(2, Height-6); Write('Total Area = ',Geometric:10:2,' sq.',units); end; Macro 'Measure Length [L]'; begin if (lThick = 0) then lThick:=1; SetLineWidth(lThick); Geometric:=rLength[rCount]; expon:=1; DrawBoundary; KillRoi; SetCounter(clickCount); end; macro '(---'; begin end; {Random Numbers Macros, rev. May 18, 1994} {Press U to set the upper limit for a given session and to generate a random integer between 1 and the upperlimit. R generates random integers between 1 and the upperlimit.} Procedure RandomNumber; begin repeat randomvalue:=round(random*rlimit); until randomvalue > 0; end; Procedure UpperLimit; begin rlimit:=GetNumber('Upper limit?',30); RandomNumber; PutMessage(randomvalue); end; Macro 'Upper Limit for Random Numbers [U]'; begin UpperLimit; end; Macro 'Random Numbers [R]'; begin if rlimit = 0 then UpperLimit; if rlimit > 0 then begin RandomNumber; PutMessage(randomvalue); end; end; Macro 'List of Random Numbers [N]'; var howmany:integer; begin SetOptions('User1'); SetUser1Label('Random'); rlimit:=GetNumber('Upper limit?',10); HowMany:=GetNumber('How many random numbers?',30); for r:=1 to HowMany do begin SetCounter(rCount+1); RandomNumber; rUser1[rCount]:=randomvalue; UpDateResults; end; end; macro '(---'; begin end; Macro 'Read Current Scale [A]'; begin Checkforpic; PutMessage('Scale:',Pelpermicron:6:2, ' pixels per ',units,'; Aspect ratio (x/y): ',PAspectRatio:6:4,'; Current tile area: ', TileArea:6:2,' sq. ',units,'; Line length: ',sqrt(TileArea):6:2,' ',units,'.'); end; Macro 'Set Grid Color [G]'; begin SetPalette('',6); ShowMessage(' Red is 1 \ Green is 2 \ Blue is 3 \ Yellow is 4 \ Aqua is 5 \ Magenta is 6 \ White is 8 \ Black is 255 \ The default is red (1)'); if (color = 0) then color:=1; color:=GetNumber('What color for the grid?',color,0); end; Macro 'Set Random Start Area'; begin ShowMessage('The grid origin is placed randomly in the image upper left corner within N multiples of the tile area. The default is the area of 1 tile (1). Zero (0) forces the origin to the top left corner.'); if (RandomMacroCalled = 0) then startinterval:=1; {sets default to 1} startinterval:=GetNumber('Random region X tile area:',startinterval,0); RandomMacroCalled:=1; {indicate that the user has been to this macro} end; Macro 'Set Margin Width'; begin if (BdyMacroCalled = 0) then Bdy:=10; Bdy:=GetNumber('Min. boundary between template and top & left image: ',Bdy); BdyMacroCalled:= 1; end; Macro 'Set Line Thickness'; begin if (lthick = 0) then lthick:=1; lthick:=GetNumber('Lines will be this many pixels thick:',lthick,0); end; Macro 'Set Spot Diameter'; begin IfSpotDia; spotdia:=GetNumber('Spot template diameter (pixels):',spotdia,0); end;