; Event handler routine for main window PRO browser_event, ev WIDGET_CONTROL, ev.top, GET_UVALUE = data ; case where main window is resized if(ev.id eq ev.top)then begin uv='not a real user value...' data.control.ysize=ev.y-data.panelheight data.control.xsize=(data.control.ysize)*(4.0/3.0) WIDGET_CONTROL, data.control.grwin, XSIZE = data.control.xsize,YSIZE = data.control.ysize ; WIDGET_CONTROL, data.control.grwin, YSIZE = data.control.ysize WIDGET_CONTROL, data.control.xrotslide, YSIZE=data.control.ysize WIDGET_CONTROL, data.control.yrotslide, XSIZE=data.control.xsize*0.5 WIDGET_CONTROL, data.control.zoomslide, XSIZE=data.control.xsize*0.5 WIDGET_CONTROL, data.control.xrotslide, SCR_YSIZE=data.control.ysize WIDGET_CONTROL, data.control.yrotslide, SCR_XSIZE=data.control.xsize*0.5 WIDGET_CONTROL, data.control.zoomslide, SCR_XSIZE=data.control.xsize*0.5 WIDGET_CONTROL, ev.top, SET_UVALUE = data endif else begin WIDGET_CONTROL, ev.id, GET_UVALUE = uv endelse if (uv eq 'EXIT') THEN WIDGET_CONTROL, ev.top, /DESTROY if (uv eq 'OPEN') THEN fileopen, ev.top, 0 if (uv eq 'OPEN_HDF5') THEN fileopen, ev.top, 1 if (uv eq 'READREGION') then begin read_milli_region, ev.top endif ; Controls only work if data loaded if (data.loaded gt 0) then begin if (uv eq 'YRSLIDER' or uv eq 'XRSLIDER') THEN redraw, ev.top if (uv eq 'ZOOMSLIDER') THEN redraw, ev.top if (uv eq 'UP' ) THEN move, ev.top, uv if (uv eq 'DOWN' ) THEN move, ev.top, uv if (uv eq 'LEFT' ) THEN move, ev.top, uv if (uv eq 'RIGHT' ) THEN move, ev.top, uv if (uv eq 'FWD' ) THEN move, ev.top, uv if (uv eq 'BACK' ) THEN move, ev.top, uv if (uv eq 'PROPS' ) THEN fileprops, ev.top if (uv eq 'SPECIES0') then begin data.ispecies=0 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'SPECIES1') then begin data.ispecies=1 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'SPECIES2') then begin data.ispecies=2 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'SPECIES3') then begin data.ispecies=3 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'SPECIES4') then begin data.ispecies=4 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'SPECIES5') then begin data.ispecies=5 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'VIEWMIN') then begin data.nshow=50000L ;data.range.selectsize=0.0 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'VIEWMED') then begin data.nshow=100000L ;data.range.selectsize=0.0 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'VIEWHIGH') then begin data.nshow=200000L ;data.range.selectsize=0.0 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'VIEWMAX') then begin data.nshow=500000L ;data.range.selectsize=0.0 WIDGET_CONTROL, ev.top, SET_UVALUE=data changeispecies, ev.top redraw, ev.top endif if (uv eq 'ADDWAYPOINT') then begin data.waypoint.npoints=data.waypoint.npoints+1 data.waypoint.x[data.waypoint.npoints-1] = data.range.selectx data.waypoint.y[data.waypoint.npoints-1] = data.range.selecty data.waypoint.z[data.waypoint.npoints-1] = data.range.selectz WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Waypoint "+string(data.waypoint.npoints,"(i3)")+" added" WIDGET_CONTROL, ev.top, SET_UVALUE=data endif if (uv eq 'CLEARWAYPOINTS') then begin data.waypoint.npoints=0 WIDGET_CONTROL, data.control.statusbar, SET_VALUE="All waypoints cleared" WIDGET_CONTROL, ev.top, SET_UVALUE=data endif if (uv eq 'GREY') then begin WIDGET_CONTROL,data.control.viewscheme,SENSITIVE=1 if(TOTAL(data.header.np) gt data.header.np(1))then begin if(data.ispecies eq 0)then loadct,3,/SILENT if(data.ispecies eq 1)then loadct,8,/SILENT if(data.ispecies eq 2)then loadct,8,/SILENT if(data.ispecies eq 3)then loadct,8,/SILENT if(data.ispecies eq 4)then loadct,1,/SILENT if(data.ispecies eq 5)then loadct,8,/SILENT endif data.viewtype=0 WIDGET_CONTROL, ev.top, SET_UVALUE=data redraw, ev.top endif if (uv eq 'GREYSMOOTH') then begin data.viewtype=3 if(TOTAL(data.header.np) gt data.header.np(1))then begin if(data.ispecies eq 0)then loadct,3,/SILENT if(data.ispecies eq 1)then loadct,8,/SILENT if(data.ispecies eq 2)then loadct,8,/SILENT if(data.ispecies eq 3)then loadct,8,/SILENT if(data.ispecies eq 4)then loadct,1,/SILENT if(data.ispecies eq 5)then loadct,8,/SILENT endif WIDGET_CONTROL,data.control.viewscheme,SENSITIVE=1 WIDGET_CONTROL, ev.top, SET_UVALUE=data redraw, ev.top endif if (uv eq 'MONO') then begin WIDGET_CONTROL,data.control.viewscheme,SENSITIVE=0 r=[0,255,255] g=[0,255,0] b=[0,255,0] tvlct,r,g,b data.viewtype=2 WIDGET_CONTROL, ev.top, SET_UVALUE=data redraw, ev.top endif if (uv eq 'STEREO') then begin WIDGET_CONTROL,data.control.viewscheme,SENSITIVE=0 data.viewtype=1 WIDGET_CONTROL, ev.top, SET_UVALUE=data redraw, ev.top endif if (uv eq 'SELECTREGION') then begin region_select, ev.top endif if (uv eq 'SELECTCANCEL') then begin cancel_select, ev.top endif if (uv eq 'RESET') then begin ;data.range.selectx=0.0 ;data.range.selecty=0.0 ;data.range.selectz=0.0 ;data.range.selectsize=0.0 WIDGET_CONTROL,data.control.grwin,GET_UVALUE=winstat winstat.xtrans=0.0 winstat.ytrans=0.0 winstat.ztrans=6.0 WIDGET_CONTROL,data.control.grwin,SET_UVALUE=winstat WIDGET_CONTROL,data.control.yrotslide,SET_VALUE=180 WIDGET_CONTROL,data.control.xrotslide,SET_VALUE=180 WIDGET_CONTROL,data.control.zoomslide,SET_VALUE=50 WIDGET_CONTROL, ev.top, SET_UVALUE=data ;changeispecies, ev.top redraw,ev.top endif if(uv eq 'WRITEASCII')then begin write_ascii, ev.top endif if(uv eq 'MAKEIMAGE')then begin makejpegimage, ev.top endif if(uv eq 'BRIGHTSLIDER') then redraw, ev.top if(uv eq 'COLSCHEME')then xloadct,/SILENT,GROUP=ev.top,/MODAL if(uv eq 'EXPORT') then export_coords,ev.top if(uv eq 'ROTMOVIE') then rotmovie,ev.top if(uv eq 'PATHMOVIE') then pathmovie,ev.top if(uv eq 'EVOLMOVIE') then evolmovie,ev.top if(uv eq 'EDITWAYPOINTS') then edit_waypoints, ev.top if(uv eq 'WRITEWAYPOINTS' and data.waypoint.npoints gt 0)then begin openw, lun, "waypoints.txt",/get_lun for i=0,data.waypoint.npoints-1,1 do begin printf,lun,data.waypoint.x[i],data.waypoint.y[i],data.waypoint.z[i],format="(3e16.8)" endfor free_lun,lun WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Wrote waypoint coordinates to waypoints.txt" endif if(uv eq 'NEXTSNAP') then nextsnap, ev.top, 1 if(uv eq 'PREVSNAP') then nextsnap, ev.top, -1 if(uv eq 'SETSNAP') then nextsnap, ev.top, 0 endif if(uv eq "HELPCONTROLS") then helpcontrols, ev.top if(uv eq "HELPVERSION") then begin junk = DIALOG_MESSAGE(["Gadget file viewer 1.0 - last modified 04-10-2005"," ","Email: j.c.helly@dur.ac.uk"],/INFORMATION) endif END function zoomfac, zoom return, 0.5*(2^(zoom/50.0)) end pro helpcontrols, top helpwin = WIDGET_BASE(TITLE="Controls",GROUP_LEADER=top) txtarr = strarr(20) txtarr(0) =' ' txtarr(1) =' View Controls:' txtarr(2) =' ---------------' txtarr(3) =' ' txtarr(4) =' Hold button 1 + drag left/right : Rotate view about y axis' txtarr(5) =' Hold button 1 + drag up/down : Zoom in/out' txtarr(6) =' ' txtarr(7) =' Hold button 2 + drag any dir. : Move view in plane of screen' txtarr(8) =' ' txtarr(9) =' Click button 3 on a point : Select median (3D) position of nearby' txtarr(10) =' particles as centre of rotation' txtarr(11) =' ' txtarr(12) =' Hold button 3 + drag : Move waypoint in plane of screen' txtarr(13) =' ' txtarr(14) =' Use the "View/Select region..." menu option to get a closer view' txtarr(15) =' of individual objects showing a greater fraction of the particles.' text = WIDGET_TEXT(helpwin,YSIZE=18,XSIZE=80,VALUE=txtarr) WIDGET_CONTROL, helpwin, /REALIZE XMANAGER, 'browser', helpwin, /NO_BLOCK end pro nextsnap, top, idir WIDGET_CONTROL, top, GET_UVALUE=data WIDGET_CONTROL, data.control.setsnap, GET_VALUE=snap isnap=FIX(snap) isnap=isnap+idir if(data.milli.loaded eq 0) then begin fname = data.filename i=strpos(fname,"_",/REVERSE_SEARCH) istr = string(isnap,"(i3.3)") strput, fname, istr, i+1 readsnap, fname, data, npartread, hdr, pos, success if(success ne 1) then begin junk=DIALOG_MESSAGE("Unable to find file: "+fname,/ERROR,DIALOG_PARENT=top) return endif x = pos(0,0:npartread-1) y = pos(1,0:npartread-1) z = pos(2,0:npartread-1) endif else begin if(isnap lt 8 or isnap gt 63) then begin junk=DIALOG_MESSAGE("Snapshot number must be in range 8-63",/ERROR,DIALOG_PARENT=top) return endif WIDGET_CONTROL, /HOURGLASS WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Reading data..." xmin = data.milli.xmin xmax = data.milli.xmax ymin = data.milli.ymin ymax = data.milli.ymax zmin = data.milli.zmin zmax = data.milli.zmax npmax = 40000000L x=fltarr(npmax) y=fltarr(npmax) z=fltarr(npmax) npart=0L zred=0.0 isnap = long(isnap) ierr = CALL_EXTERNAL( $ "/home/jch/IDL/GadgetViewer/idl_read_region.so", $ "idl_read_region",isnap,xmin,xmax,ymin,ymax, $ zmin,zmax,npart,x,y,z,npmax,/I_VALUE) print, zred hdr = data.header hdr.omega0=0.25 hdr.lambda=0.75 hdr.massarr=hdr.massarr*0.0 hdr.massarr(1)=8.60657e-2 hdr.h0=0.73 hdr.np(0:5)=0 hdr.np(1)=npart hdr.boxsize=500.0 hdr.expansion=double(1.0/(1.0+zred)) hdr.redshift=double(zred) data.filename='Millennium data for snapshot '+string(isnap,format="(1i3.3)") data.ispecies=1 endelse ptr_free, data.xptr ptr_free, data.yptr ptr_free, data.zptr data.xptr = ptr_new(x,/no_copy) data.yptr = ptr_new(y,/no_copy) data.zptr = ptr_new(z,/no_copy) data.header=hdr if(data.header.np[data.ispecies] eq 0) then begin junk=DIALOG_MESSAGE("This snapshot has no particles of the specified type",/ERROR,DIALOG_PARENT=top) i = where(data.header.np gt 0) data.ispecies = i[0] endif WIDGET_CONTROL, top, SET_UVALUE=data changeispecies, top redraw, top WIDGET_CONTROL, data.control.setsnap, SET_VALUE=isnap end pro pathmovie, top WIDGET_CONTROL, top, GET_UVALUE=data if(data.waypoint.npoints lt 2) then begin junk=DIALOG_MESSAGE("You need to set at least two waypoints for a fly through!",/ERROR,DIALOG_PARENT=top) return endif ; Get filename and number of frames filename = DIALOG_PICKFILE(DIALOG_PARENT=top,PATH=data.path,/WRITE,FILTER="*.mpg",GET_PATH=path) if(filename eq "") then return check_file, filename, path, iwrite, top if(iwrite eq 0) then return desc = [ $ '0,INTEGER,200,WIDTH=6,TAG=nframe, LABEL_LEFT=Number of frames in movie:', $ '0,INTEGER,640,WIDTH=6,TAG=nx, LABEL_LEFT=Width in pixels:', $ '0,INTEGER,480,WIDTH=6,TAG=ny, LABEL_LEFT=Height in pixels:', $ '0,INTEGER,100, WIDTH=6,TAG=qual, LABEL_LEFT=MPEG quality (1-100):', $ '1, BASE,, ROW', $ '0, BUTTON,Make Movie, QUIT, TAG=OK', $ '2, BUTTON,Cancel, QUIT'] res = CW_FORM(desc,/column,title="Movie Parameters",group_leader=top) if(res.ok ne 1) then return nx=res.nx ny=res.ny ; Get coordinates of points along flightpath xp = DOUBLE(data.waypoint.x[0:data.waypoint.npoints-1]) yp = DOUBLE(data.waypoint.y[0:data.waypoint.npoints-1]) zp = DOUBLE(data.waypoint.z[0:data.waypoint.npoints-1]) if(data.waypoint.npoints gt 2) then begin t = dindgen(data.waypoint.npoints)/DOUBLE(data.waypoint.npoints-1) tout = dindgen(res.nframe)/DOUBLE(res.nframe-1) xspline = SPLINE(t,xp,tout,0.1) yspline = SPLINE(t,yp,tout,0.1) zspline = SPLINE(t,zp,tout,0.1) endif else begin t = findgen(data.waypoint.npoints)/float(data.waypoint.npoints-1) tout = findgen(res.nframe)/float(res.nframe-1) xspline = INTERPOL(xp,t,tout) yspline = INTERPOL(yp,t,tout) zspline = INTERPOL(zp,t,tout) endelse ; Transform to coordinate system of the selected particles if(data.range.selectsize gt 0.0)then begin scl = DOUBLE((1.0/data.range.selectsize)*2.0) xspline=(xspline-data.range.selectx)*scl yspline=(yspline-data.range.selecty)*scl zspline=(zspline-data.range.selectz)*scl endif else begin scl = DOUBLE((1.0/data.range.maxsize)*2.0) xspline=(xspline-data.range.xc)*scl yspline=(yspline-data.range.yc)*scl zspline=(zspline-data.range.zc)*scl endelse WIDGET_CONTROL, data.control.brightslide, GET_VALUE=bright ; WIDGET_CONTROL, data.control.zoomslide, GET_VALUE=zoom ; Will usually be closer in so scale up particle brightness ; to compensate for low surface density on the screen ; bright=bright*(zoom^0.5)*0.75 bright=bright*3.0 WIDGET_CONTROL,/HOURGLASS WIDGET_CONTROL, top, SENSITIVE=0 tvlct,rcol,gcol,bcol,/GET WIDGET_CONTROL, data.control.grwin, GET_VALUE = win_num WSET, win_num mpegid = MPEG_OPEN([nx,ny],FILENAME=filename,QUALITY=res.qual) for i=1,res.nframe-1 do begin WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Adding frame "+string(i)+" of "+string(res.nframe) xtemp = *(data.plotx)-xspline[i-1] ytemp = *(data.ploty)-yspline[i-1] ztemp = *(data.plotz)-zspline[i-1] vx = xspline[i]-xspline[i-1] vy = yspline[i]-yspline[i-1] vz = zspline[i]-zspline[i-1] r=sqrt(vx*vx+vy*vy+vz*vz) zvec=DOUBLE([vx/r,vy/r,vz/r]) yaxis=DOUBLE([0.0,1.0,0.0]) xvec=CROSSP(zvec,yaxis) xvec=xvec/sqrt(xvec[0]*xvec[0]+xvec[1]*xvec[1]+xvec[2]*xvec[2]) yvec=CROSSP(zvec,xvec) yvec=yvec/sqrt(yvec[0]*yvec[0]+yvec[1]*yvec[1]+yvec[2]*yvec[2]) x1 = xvec[0]*xtemp + xvec[1]*ytemp + xvec[2]*ztemp y1 = yvec[0]*xtemp + yvec[1]*ytemp + yvec[2]*ztemp z1 = zvec[0]*xtemp + zvec[1]*ytemp + zvec[2]*ztemp if(data.viewtype eq 0 or data.viewtype eq 3) then $ makegreyscaleimage, img, x1, y1, z1, res.nx, res.ny, bright if(data.viewtype eq 1) then makestereoimage, img, x1, y1, z1, res.nx, res.ny if(data.viewtype eq 2) then makedotplot, img, x1, y1, z1, res.nx, res.ny if(data.viewtype eq 3)then img=SMOOTH(img,3,/EDGE_TRUNCATE) colimg = bytarr(3,nx,ny) colimg[0,0:nx-1,0:ny-1] = rcol[img] colimg[1,0:nx-1,0:ny-1] = gcol[img] colimg[2,0:nx-1,0:ny-1] = bcol[img] MPEG_PUT, mpegid, IMAGE=colimg,FRAME=i-1 tv, colimg, true=1 endfor WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Writing MPEG file..." mpeg_save, mpegid mpeg_close, mpegid WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Finished writing MPEG file" WIDGET_CONTROL, top, SENSITIVE=1 end pro evolmovie, top WIDGET_CONTROL, top, GET_UVALUE=data ; Get filename, snapshot indices and number of frames filename = DIALOG_PICKFILE(DIALOG_PARENT=top,PATH=data.path,/WRITE,FILTER="*.mpg",GET_PATH=path) if(filename eq "") then return check_file, filename, path, iwrite, top if(iwrite eq 0) then return WIDGET_CONTROL, data.control.setsnap, GET_VALUE=str desc = [ $ '1,BASE,,ROW',$ '0,INTEGER,1,WIDTH=6,TAG=ifirst, LABEL_LEFT=First snapshot:', $ '2,INTEGER,'+string(str)+',WIDTH=6,TAG=ilast, LABEL_LEFT=Last snapshot', $ '0,BUTTON,Interpolate frames|One frame per snapshot,EXCLUSIVE,ROW,tag=interp,SET_VALUE=0',$ '0,INTEGER,180,WIDTH=6,TAG=nframe, LABEL_LEFT=Number of frames in movie (if interpolating):', $ '1,BASE,,ROW',$ '0,INTEGER,640,WIDTH=6,TAG=nx, LABEL_LEFT=Width in pixels:', $ '2,INTEGER,480,WIDTH=6,TAG=ny, LABEL_LEFT=Height in pixels:', $ '0,INTEGER,100, WIDTH=6,TAG=qual, LABEL_LEFT=MPEG quality (1-100):', $ '0,BUTTON,Center on current view|Center on center of mass,EXCLUSIVE,ROW,tag=bg1,SET_VALUE=0', $ '1, BASE,, ROW', $ '0, BUTTON,Make Movie, QUIT, TAG=OK', $ '2, BUTTON,Cancel, QUIT'] res = CW_FORM(desc,/column,title="Movie Parameters",group_leader=top) if(res.ok ne 1) then return snapfile = data.filename ichar = strpos(snapfile,"_",/reverse_search) ifirst = res.ifirst ilast = res.ilast nx = res.nx ny = res.ny nframe = res.nframe qual = res.qual ; Check that all of the snapshot files exist and get times WIDGET_CONTROL, top, SENSITIVE = 0 WIDGET_CONTROL, /HOURGLASS fileaexp = fltarr(ilast-ifirst+1) iok = 1 for i=ifirst,ilast do begin strput,snapfile,string(i,"(i3.3)"),ichar+1 if(file_test(snapfile) eq 0) then iok = 0 if(res.interp eq 1)then begin readsnap, snapfile, data, npartread,hdr,pos,success, /header_only fileaexp[i-ifirst] = float(hdr.expansion) endif endfor if(iok eq 0) then begin junk=DIALOG_MESSAGE("Some of the required snapshots appear to be missing!",/ERROR,DIALOG_PARENT=top) WIDGET_CONTROL, data.control.statusbar, SET_VALUE="No movie file written." WIDGET_CONTROL, top, SENSITIVE=1 return endif if(ifirst ge ilast) then begin junk=DIALOG_MESSAGE("The first snapshot must be earlier than the last one!",/ERROR,DIALOG_PARENT=top) WIDGET_CONTROL, data.control.statusbar, SET_VALUE="No movie file written." WIDGET_CONTROL, top, SENSITIVE=1 return endif WIDGET_CONTROL, top, SENSITIVE=0 ; Get redshifts from first and last files strput,snapfile,string(ilast,"(i3.3)"),ichar+1 readsnap, snapfile, data, npartread, hdr, pos, success afinal = hdr.expansion strput,snapfile,string(ifirst,"(i3.3)"),ichar+1 readsnap, snapfile, data, npartread, hdr, pos, success astart = hdr.expansion ; Make array of redshifts for movie frames if(data.header.boxsize gt 0.0) then begin lafinal = alog10(afinal) lastart = alog10(astart) aexpand = findgen(nframe)/float(nframe-1) * (lafinal-lastart) + lastart aexpand = 10.0^aexpand endif else begin aexpand = astart + (findgen(nframe)/float(nframe-1))*(afinal-astart) endelse if(res.interp eq 1) then begin aexpand = fileaexp nframe = n_elements(aexpand) endif ; Read in first two snapshots strput,snapfile,string(ifirst,"(i3.3)"),ichar+1 readsnap, snapfile, data, npartread1, hdr1, pos1, success, ID=id1 strput,snapfile,string(ifirst+1,"(i3.3)"),ichar+1 readsnap, snapfile, data, npartread2, hdr2, pos2, success, ID=id2 if(hdr1.np[data.ispecies] eq 0 or hdr2.np[data.ispecies] eq 0) then begin junk=DIALOG_MESSAGE("Snapshot contains no particles of the required type!",/ERROR,DIALOG_PARENT=top) WIDGET_CONTROL, data.control.statusbar, SET_VALUE="No movie file written." WIDGET_CONTROL, top, SENSITIVE=1 return endif if(res.interp eq 0) then sort_particles, hdr1, hdr2, id1, id2, pos1, pos2, data.ispecies isnap = ifirst ; Open movie file mpegid = MPEG_OPEN([nx,ny],FILENAME=filename,QUALITY=qual) ; Get current view settings WIDGET_CONTROL, data.control.grwin, GET_UVALUE=winstat WIDGET_CONTROL, data.control.xrotslide, GET_VALUE=xrot WIDGET_CONTROL, data.control.yrotslide, GET_VALUE=yrot WIDGET_CONTROL, data.control.zoomslide, GET_VALUE=zoom zoom=zoomfac(zoom) thetay=DOUBLE(yrot/180.0*3.14159) thetax=DOUBLE(xrot/180.0*3.14159) tvlct,rcol,gcol,bcol,/GET WIDGET_CONTROL, data.control.brightslide, GET_VALUE=bright bright=bright*(zoom^0.5)*0.75 ; Loop over frames for iframe = 0, nframe-1, 1 do begin WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Adding frame "+string(iframe)+" of "+string(nframe) aframe = aexpand[iframe] a1 = hdr1.expansion a2 = hdr2.expansion ; Check if we need to read another snapshot if(aframe gt a2 and isnap lt ilast-1) then begin isnap=isnap+1 strput,snapfile,string(isnap,"(i3.3)"),ichar+1 readsnap, snapfile, data, npartread1, hdr1, pos1, success, ID=id1 if(success eq 0)then begin junk=DIALOG_MESSAGE("Failed reading file "+snapfile,/ERROR,DIALOG_PARENT=top) WIDGET_CONTROL, data.control.statusbar, SET_VALUE="No movie file written." WIDGET_CONTROL, top, SENSITIVE=1 return endif if(res.interp eq 0)then begin strput,snapfile,string(isnap+1,"(i3.3)"),ichar+1 readsnap, snapfile, data, npartread2, hdr2, pos2, success, ID=id2 if(success eq 0)then begin junk=DIALOG_MESSAGE("Failed reading file "+snapfile,/ERROR,DIALOG_PARENT=top) WIDGET_CONTROL, data.control.statusbar, SET_VALUE="No movie file written." WIDGET_CONTROL, top, SENSITIVE=1 return endif a1 = hdr1.expansion a2 = hdr2.expansion if(hdr1.np[data.ispecies] eq 0 or hdr2.np[data.ispecies] eq 0) then begin junk=DIALOG_MESSAGE("Snapshot contains no particles of the required type!",/ERROR,DIALOG_PARENT=top) WIDGET_CONTROL, data.control.statusbar, SET_VALUE="No movie file written." WIDGET_CONTROL, top, SENSITIVE=1 return endif sort_particles, hdr1, hdr2, id1, id2, pos1, pos2, data.ispecies endif else begin a1 = hdr1.expansion a2 = a1 hdr2 = hdr1 endelse endif ; Get particle positions at this redshift by linear interpolation if(res.interp eq 0)then begin if(data.header.boxsize gt 0.0)then begin la1 = alog10(a1) la2 = alog10(a2) laint = alog10(aframe) xtemp = pos1(0,*) + (pos2(0,*)-pos1(0,*)) * (laint-la1)/(la2-la1) ytemp = pos1(1,*) + (pos2(1,*)-pos1(1,*)) * (laint-la1)/(la2-la1) ztemp = pos1(2,*) + (pos2(2,*)-pos1(2,*)) * (laint-la1)/(la2-la1) endif else begin xtemp = pos1(0,*) + (pos2(0,*)-pos1(0,*)) * (aframe-a1)/(a2-a1) ytemp = pos1(1,*) + (pos2(1,*)-pos1(1,*)) * (aframe-a1)/(a2-a1) ztemp = pos1(2,*) + (pos2(2,*)-pos1(2,*)) * (aframe-a1)/(a2-a1) endelse endif else begin ispecies=data.ispecies ifirst=0L if(ispecies gt 0)then ifirst=LONG(TOTAL(LONG(hdr1.np(0:ispecies-1)))) ilast=ifirst+LONG(hdr1.np(ispecies))-1L xtemp = pos1(0,ifirst:ilast) ytemp = pos1(1,ifirst:ilast) ztemp = pos1(2,ifirst:ilast) endelse ; Transform to 'selected species' coordinate system if(res.bg1 eq 0) then begin if(data.range.selectsize gt 0.0)then begin scl = (1.0/data.range.selectsize)*2.0 xtemp=(xtemp-data.range.selectx)*scl ytemp=(ytemp-data.range.selecty)*scl ztemp=(ztemp-data.range.selectz)*scl endif else begin scl = (1.0/data.range.maxsize)*2.0 xtemp=(xtemp-data.range.xc)*scl ytemp=(ytemp-data.range.yc)*scl ztemp=(ztemp-data.range.zc)*scl endelse endif else begin ; Center on center of mass if necessary cx = TOTAL(xtemp)/N_ELEMENTS(xtemp) cy = TOTAL(ytemp)/N_ELEMENTS(ytemp) cz = TOTAL(ztemp)/N_ELEMENTS(ztemp) if(data.range.selectsize gt 0.0)then begin scl = (1.0/data.range.selectsize)*2.0 xtemp=(xtemp-cx)*scl ytemp=(ytemp-cy)*scl ztemp=(ztemp-cz)*scl endif else begin scl = (1.0/data.range.maxsize)*2.0 xtemp=(xtemp-cx)*scl ytemp=(ytemp-cy)*scl ztemp=(ztemp-cz)*scl endelse endelse ; Apply rotation/zoom/translation to match display x=(xtemp*cos(thetay)+(ytemp*sin(thetax)-ztemp*cos(thetax))*sin(thetay))*zoom+winstat.xtrans y=(ytemp*cos(thetax)+ztemp*sin(thetax))*zoom+winstat.ytrans z=(xtemp*sin(thetay)+(ztemp*cos(thetax)-ytemp*sin(thetax))*cos(thetay))*zoom+winstat.ztrans ; Make the image if(data.viewtype eq 0 or data.viewtype eq 3) then $ makegreyscaleimage, img, x, y, z, nx, ny, bright if(data.viewtype eq 1) then makestereoimage, img, x, y, z, nx, ny if(data.viewtype eq 2) then makedotplot, img, x, y, z, nx, ny if(data.viewtype eq 3) then img=SMOOTH(img,3,/EDGE_TRUNCATE) colimg = bytarr(3,nx,ny) colimg[0,0:nx-1,0:ny-1] = rcol[img] colimg[1,0:nx-1,0:ny-1] = gcol[img] colimg[2,0:nx-1,0:ny-1] = bcol[img] MPEG_PUT, mpegid, IMAGE=colimg,FRAME=iframe tv, colimg, true=1 endfor WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Writing MPEG file..." mpeg_save, mpegid mpeg_close, mpegid WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Finished writing MPEG file" WIDGET_CONTROL, top, SENSITIVE=1 end pro sort_particles, hdr1, hdr2, id1, id2, pos1, pos2, ispecies ; Sort both sets of particles and discard those not present ; in both snapshots or not of the required species ifirst=0L if(ispecies gt 0)then ifirst=LONG(TOTAL(LONG(hdr1.np(0:ispecies-1)))) ilast=ifirst+LONG(hdr1.np(ispecies))-1L id1 = id1(ifirst:ilast) pos1 = pos1(*,ifirst:ilast) ifirst=0L if(ispecies gt 0)then ifirst=LONG(TOTAL(LONG(hdr2.np(0:ispecies-1)))) ilast=ifirst+LONG(hdr2.np(ispecies))-1L id2 = id2(ifirst:ilast) pos2 = pos2(*,ifirst:ilast) np1 = N_ELEMENTS(id1) np2 = N_ELEMENTS(id2) sortidx = sort(id1) id1 = id1[sortidx] pos1[0,*] = pos1[0,sortidx] pos1[1,*] = pos1[1,sortidx] pos1[2,*] = pos1[2,sortidx] sortidx = sort(id2) id2 = id2[sortidx] pos2[0,*] = pos2[0,sortidx] pos2[1,*] = pos2[1,sortidx] pos2[2,*] = pos2[2,sortidx] flag1 = intarr(np1) flag2 = intarr(np2) i1 = 0L i2 = 0L for i1 = 0L,np1-1L,1L do begin while( id2[i2] lt id1[i1] and i2 lt np2-1) do i2 = i2 + 1L if(id2[i2] eq id1[i1]) then begin flag1[i1] = 1 flag2[i2] = 1 endif endfor idx = where(flag1 eq 1) new_np1 = N_ELEMENTS(idx) temp_pos = fltarr(3,new_np1) temp_pos[0,*] = pos1[0,idx] temp_pos[1,*] = pos1[1,idx] temp_pos[2,*] = pos1[2,idx] pos1 = temp_pos np1 = new_np1 idx = where(flag2 eq 1) new_np2 = N_ELEMENTS(idx) temp_pos = fltarr(3,new_np2) temp_pos[0,*] = pos2[0,idx] temp_pos[1,*] = pos2[1,idx] temp_pos[2,*] = pos2[2,idx] pos2 = temp_pos np2 = new_np2 end pro rotmovie, top WIDGET_CONTROL, top, GET_UVALUE=data ; Get filename, number of degrees to rotate and number of frames filename = DIALOG_PICKFILE(DIALOG_PARENT=top,PATH=data.path,/WRITE,FILTER="*.mpg",GET_PATH=path) if(filename eq "") then return check_file, filename, path, iwrite, top if(iwrite eq 0) then return desc = [ $ '0,INTEGER,360,WIDTH=6,TAG=ndeg, LABEL_LEFT=Number of degrees to rotate:', $ '0,INTEGER,180,WIDTH=6,TAG=nframe, LABEL_LEFT=Number of frames in movie:', $ '0,INTEGER,640,WIDTH=6,TAG=nx, LABEL_LEFT=Width in pixels:', $ '0,INTEGER,480,WIDTH=6,TAG=ny, LABEL_LEFT=Height in pixels:', $ '0,INTEGER,100, WIDTH=6,TAG=qual, LABEL_LEFT=MPEG quality (1-100):', $ '1, BASE,, ROW', $ '0, BUTTON,Make Movie, QUIT, TAG=OK', $ '2, BUTTON,Cancel, QUIT'] res = CW_FORM(desc,/column,title="Movie Parameters",group_leader=top) if(res.ok ne 1) then return WIDGET_CONTROL,/HOURGLASS WIDGET_CONTROL, top, SENSITIVE=0 oldnx = data.control.xsize oldny = data.control.ysize data.control.xsize=res.nx data.control.ysize=res.ny nx=res.nx ny=res.ny WIDGET_CONTROL,top,SET_UVALUE=data WIDGET_CONTROL, data.control.statusbar, SENSITIVE=1 tvlct,r,g,b,/GET WIDGET_CONTROL, data.control.grwin, GET_VALUE = win_num WSET, win_num mpegid = MPEG_OPEN([nx,ny],FILENAME=filename,QUALITY=res.qual) for i=1,res.nframe do begin WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Adding frame "+string(i)+" of "+string(res.nframe) theta = float(i)*float(res.ndeg)/float(res.nframe) WIDGET_CONTROL, top, GET_UVALUE=data WIDGET_CONTROL, data.control.yrotslide, SET_VALUE=theta WIDGET_CONTROL, top, SET_UVALUE=data redraw, top, img colimg = bytarr(3,nx,ny) colimg[0,0:nx-1,0:ny-1] = r[img] colimg[1,0:nx-1,0:ny-1] = g[img] colimg[2,0:nx-1,0:ny-1] = b[img] MPEG_PUT, mpegid, IMAGE=colimg,FRAME=i-1 tv, colimg, true = 1 endfor WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Writing MPEG file..." mpeg_save, mpegid mpeg_close, mpegid WIDGET_CONTROL, data.control.statusbar, SET_VALUE="Finished writing MPEG file" WIDGET_CONTROL, top, SENSITIVE=1 data.control.xsize=oldnx data.control.ysize=oldny WIDGET_CONTROL,top,SET_UVALUE=data end PRO fileopen, top, hdf5 ; Read the gadget file WIDGET_CONTROL, top, GET_UVALUE=data filename = DIALOG_PICKFILE(DIALOG_PARENT=top,PATH=data.path,GET_PATH=path,/MUST_EXIST,/READ) if (filename ne '' ) then begin WIDGET_CONTROL, /HOURGLASS data.path=path data.range.selectsize=0.0 data.hdf5 = hdf5 readsnap, filename, data, npartread, hdr, pos, success if(success eq 1)then begin i = strpos(filename,"_",/REVERSE_SEARCH) j = strpos(filename,"/",/REVERSE_SEARCH) k = strpos(filename,".",/REVERSE_SEARCH) strsnap = strmid(filename,i+1,3) ON_IOERROR, fixfailed isok = 0 isnap = fix(strsnap) isok = 1 fixfailed: ON_IOERROR, NULL ; No snapshot no. if last "_" is before the last "/" if(i ne -1 and j ne -1 and i lt j) then isok = 0 if(isok eq 1) then begin WIDGET_CONTROL, data.control.setsnap, SET_VALUE=isnap WIDGET_CONTROL, data.control.setsnap, SENSITIVE=1 WIDGET_CONTROL, data.control.nextsnap, SENSITIVE=1 WIDGET_CONTROL, data.control.prevsnap, SENSITIVE=1 endif else begin ; Failed to read the snapshot number so grey out snapshot controls WIDGET_CONTROL, data.control.setsnap, SET_VALUE=0 WIDGET_CONTROL, data.control.setsnap, SENSITIVE=0 WIDGET_CONTROL, data.control.nextsnap, SENSITIVE=0 WIDGET_CONTROL, data.control.prevsnap, SENSITIVE=0 endelse data.milli.loaded = 0 xrange = MAX(pos(0,0:npartread-1))-MIN(pos(0,0:npartread-1)) yrange = MAX(pos(1,0:npartread-1))-MIN(pos(1,0:npartread-1)) zrange = MAX(pos(2,0:npartread-1))-MIN(pos(2,0:npartread-1)) data.range.maxsize = MAX([xrange,yrange,zrange]) ; Get center of box data.range.xc = MIN(pos(0,0:npartread-1))+0.5*xrange data.range.yc = MIN(pos(1,0:npartread-1))+0.5*yrange data.range.zc = MIN(pos(2,0:npartread-1))+0.5*zrange ; No selected region data.range.selectsize = 0.0 data.range.selectx = data.range.xc data.range.selecty = data.range.yc data.range.selectz = data.range.zc WIDGET_CONTROL,data.control.grwin,GET_UVALUE=winstat winstat.xtrans=0.0 winstat.ytrans=0.0 winstat.ztrans=6.0 WIDGET_CONTROL,data.control.grwin,SET_UVALUE=winstat WIDGET_CONTROL,data.control.yrotslide,SET_VALUE=180 WIDGET_CONTROL,data.control.xrotslide,SET_VALUE=180 WIDGET_CONTROL,data.control.zoomslide,SET_VALUE=50 ; Set center of selection to center of box data.range.oldselectx=data.range.xc data.range.oldselecty=data.range.yc data.range.oldselectz=data.range.zc ; Store pointers to the particle data in base UVALUE data.header=hdr data.loaded=1 ip=where(hdr.np gt 0) data.ispecies=ip(0) data.filename=filename data.xptr=PTR_NEW(pos(0,0:npartread-1)) data.yptr=PTR_NEW(pos(1,0:npartread-1)) data.zptr=PTR_NEW(pos(2,0:npartread-1)) data.hdf5 = hdf5 WIDGET_CONTROL, top, SET_UVALUE=data ; Update plotx,y,z arrays and redraw image changeispecies, top redraw, top ; Grey out buttons for species with np=0 WIDGET_CONTROL, data.control.part_0, SENSITIVE=1 WIDGET_CONTROL, data.control.part_1, SENSITIVE=1 WIDGET_CONTROL, data.control.part_2, SENSITIVE=1 WIDGET_CONTROL, data.control.part_3, SENSITIVE=1 WIDGET_CONTROL, data.control.part_4, SENSITIVE=1 WIDGET_CONTROL, data.control.part_5, SENSITIVE=1 if(data.header.np(0) eq 0) then WIDGET_CONTROL, data.control.part_0, SENSITIVE=0 if(data.header.np(1) eq 0) then WIDGET_CONTROL, data.control.part_1, SENSITIVE=0 if(data.header.np(2) eq 0) then WIDGET_CONTROL, data.control.part_2, SENSITIVE=0 if(data.header.np(3) eq 0) then WIDGET_CONTROL, data.control.part_3, SENSITIVE=0 if(data.header.np(4) eq 0) then WIDGET_CONTROL, data.control.part_4, SENSITIVE=0 if(data.header.np(5) eq 0) then WIDGET_CONTROL, data.control.part_5, SENSITIVE=0 ; Enable menu options now we have some data WIDGET_CONTROL,data.control.file_prop,SENSITIVE=1 WIDGET_CONTROL,data.control.part_menu,SENSITIVE=1 WIDGET_CONTROL,data.control.view_menu,SENSITIVE=1 WIDGET_CONTROL,data.control.file_write,SENSITIVE=1 WIDGET_CONTROL,data.control.viewscheme,SENSITIVE=1 WIDGET_CONTROL,data.control.makeimage,SENSITIVE=1 WIDGET_CONTROL,data.control.file_export,SENSITIVE=1 WIDGET_CONTROL,data.control.waypoint_menu,SENSITIVE=1 WIDGET_CONTROL, data.control.evol_movie, SENSITIVE=1 endif else begin junk=DIALOG_MESSAGE("This doesn't appear to be a valid Gadget file!",/ERROR,DIALOG_PARENT=top) endelse endif END function gh_header,file,verbose=verbose ;Open the file: file_id = h5f_open(file) ;Open the header group: group_id = h5g_open(file_id,"Header") ;Get the number of attributes in the header: num_attrs = h5a_get_num_attrs(group_id) ;Now read in each attribute in turn: for i=0,num_attrs-1 do begin attr_id = h5a_open_idx(group_id,i) attr_name = h5a_get_name(attr_id) attr_val = h5a_read(attr_id) h5a_close,attr_id if (i eq 0) then begin GadgetHeader = create_struct(name='GadgetHeader',attr_name,attr_val) endif else begin GadgetHeader = create_struct(GadgetHeader,attr_name,attr_val) endelse if (keyword_set(verbose)) then begin print,'value : ',attr_val print,'Opening Header attribute : ',attr_name endif endfor ;Close the group and file: h5g_close,group_id h5f_close,file_id return,GadgetHeader end function gh_attr_2d,file,attr,verbose=verbose gBase = 'PartType' if (keyword_set(verbose)) then print,'Reading Gadget attribute : ',attr ;Open the file: file_id = h5f_open(file) gh = gh_header(file) ;Loop over all particle groups: count = 0 for i=0,5 do begin if (gh.NumPart_ThisFile[i] gt 0) then begin gName = gBase + string(i,format="(I1)") n_datasets = h5g_get_nmembers(file_id,gName) for j=0,n_datasets-1 do begin member_name = h5g_get_member_name(file_id,gName,j) if (strlowcase(member_name) eq strlowcase(attr)) then begin if (keyword_set(verbose)) then begin print,'Attribute ',attr,' exists for Type ',i endif group_id = h5g_open(file_id,gName) dataset_id = h5d_open(group_id,attr) pAttr_t = h5d_read(dataset_id) if (count eq 0) then begin pAttr = pAttr_t endif else begin pAttr = [[pAttr],[pAttr_t]] endelse count = count + 1 h5d_close,dataset_id h5g_close,group_id endif endfor endif endfor h5f_close,file_id return,pAttr end function gh_attr_1d,file,attr,verbose=verbose gBase = 'PartType' if (keyword_set(verbose)) then print,'Reading Gadget attribute : ',attr ;Open the file: file_id = h5f_open(file) gh = gh_header(file) ;Loop over all particle groups: count = 0 for i=0,5 do begin if (gh.NumPart_ThisFile[i] gt 0) then begin gName = gBase + string(i,format="(I1)") n_datasets = h5g_get_nmembers(file_id,gName) for j=0,n_datasets-1 do begin member_name = h5g_get_member_name(file_id,gName,j) if (strlowcase(member_name) eq strlowcase(attr)) then begin if (keyword_set(verbose)) then begin print,'Attribute ',attr,' exists for Type ',i endif group_id = h5g_open(file_id,gName) dataset_id = h5d_open(group_id,attr) pAttr_t = h5d_read(dataset_id) if (count eq 0) then begin pAttr = pAttr_t endif else begin pAttr = [pAttr,pAttr_t] endelse count = count + 1 h5d_close,dataset_id h5g_close,group_id endif endfor endif endfor h5f_close,file_id return,pAttr end pro readsnap, filename, data, npartread, hdr, pos, success, ID=id, HEADER_ONLY=header_only success=1 if(FILE_TEST(filename) eq 0) then begin success=0 return endif if (data.hdf5 eq 0) then begin OPENR, UNIT, filename, /GET_LUN ireclen = 0L READU, UNIT, ireclen FREE_LUN, UNIT if(ireclen eq 65536) then begin data.byteswap=1 OPENR, UNIT, filename,/GET_LUN,/F77_UNFORMATTED,/SWAP_ENDIAN endif if(ireclen eq 256) then begin data.byteswap=0 OPENR, UNIT, filename,/GET_LUN,/F77_UNFORMATTED endif if (ireclen eq 256 or ireclen eq 65536) then begin WIDGET_CONTROL,data.control.statusbar,SET_VALUE="Reading binary Gadget file "+filename hdr=data.header READU, UNIT, hdr npartread=LONG(LONG(hdr.np(0))+LONG(hdr.np(1))+LONG(hdr.np(2))+LONG(hdr.np(3))+LONG(hdr.np(4))+LONG(hdr.np(5))) if(KEYWORD_SET(header_only) eq 0)then begin pos=FLTARR(3,npartread) READU, UNIT, pos if(ARG_PRESENT(id)) then begin vel = FLTARR(3,npartread) READU, UNIT, vel id = lonarr(npartread) READU, UNIT, id endif endif FREE_LUN, UNIT endif else begin success = 0 endelse endif else begin ; Its a HDF5 file! if( H5F_IS_HDF5(filename) eq 0) then begin success = 0 return endif iok = 1 ;Open the file: file_id = h5f_open(filename) ;Open the header group: group_id = h5g_open(file_id,"Header") if(group_id < 0) then iok = 0 h5g_close, group_id h5f_close, file_id if(iok eq 0) then begin success = 0 return endif WIDGET_CONTROL,data.control.statusbar,SET_VALUE="Reading HDF5 Gadget file "+filename hdf5_hdr = gh_header(filename) hdr = data.header hdr.np = hdf5_hdr.NumPart_ThisFile hdr.massarr = hdf5_hdr.MassTable hdr.redshift = hdf5_hdr.Redshift hdr.expansion = hdf5_hdr.Time hdr.boxsize = hdf5_hdr.BoxSize hdr.nfiles = hdf5_hdr.NumFilesPerSnapshot hdr.omega0 = hdf5_hdr.Omega0 hdr.lambda = hdf5_hdr.OmegaLambda hdr.h0 = hdf5_hdr.HubbleParam hdr.flagsfr = hdf5_hdr.Flag_Sfr hdr.flagfb = hdf5_hdr.Flag_Feedback hdr.flagcool = hdf5_hdr.Flag_Cooling hdr.nall = hdf5_hdr.NumPart_Total npartread = TOTAL(LONG(hdr.np)) if(keyword_set(header_only) eq 0)then begin pos = gh_attr_2d(filename,"Coordinates") if(ARG_PRESENT(id))then id = gh_attr_1d(filename,"ParticleIDs") endif success = 1 endelse end PRO move, top, uv WIDGET_CONTROL, top, GET_UVALUE=data WIDGET_CONTROL, data.control.grwin, GET_UVALUE=winstat xtrans=winstat.xtrans ytrans=winstat.ytrans ztrans=winstat.ztrans IF(uv eq 'UP') THEN ytrans=ytrans+0.1 IF(uv eq 'DOWN') THEN ytrans=ytrans-0.1 IF(uv eq 'LEFT') THEN xtrans=xtrans-0.1 IF(uv eq 'RIGHT') THEN xtrans=xtrans+0.1 IF(uv eq 'FWD') THEN ztrans=ztrans+0.3 IF(uv eq 'BACK') THEN ztrans=ztrans-0.3 winstat.ztrans=ztrans winstat.xtrans=xtrans winstat.ytrans=ytrans WIDGET_CONTROL, data.control.grwin, SET_UVALUE=winstat redraw, top END PRO redraw, top, retimg ; Redraw graphics window if retimg not present, otherwise ; store the image in retimg without drawing anything on the screen. WIDGET_CONTROL, top, GET_UVALUE=data WIDGET_CONTROL, data.control.grwin, GET_UVALUE=winstat WIDGET_CONTROL, data.control.xrotslide, GET_VALUE=xrot WIDGET_CONTROL, data.control.yrotslide, GET_VALUE=yrot WIDGET_CONTROL, data.control.zoomslide, GET_VALUE=zoom zoom=zoomfac(zoom) thetay=DOUBLE(yrot/180.0*3.14159) thetax=DOUBLE(xrot/180.0*3.14159) x=(*(data.plotx)*cos(thetay)+(*(data.ploty)*sin(thetax)-*(data.plotz)*cos(thetax))*sin(thetay))*zoom+winstat.xtrans y=(*(data.ploty)*cos(thetax)+*(data.plotz)*sin(thetax))*zoom+winstat.ytrans z=(*(data.plotx)*sin(thetay)+(*(data.plotz)*cos(thetax)-*(data.ploty)*sin(thetax))*cos(thetay))*zoom+winstat.ztrans nx=data.control.xsize ny=data.control.ysize if(data.viewtype eq 1) then begin imgl=BYTARR(nx,ny) imgr=BYTARR(nx,ny) fimg=BYTARR(3,nx,ny) makestereoimage, img, x, y, z, nx,ny WIDGET_CONTROL, data.control.grwin, GET_VALUE = win_num WSET, win_num if(N_PARAMS() eq 1)then tv,img if(N_PARAMS() eq 2)then retimg = img endif else begin img=BYTARR(nx,ny) if(data.viewtype eq 0 or data.viewtype eq 3)then begin WIDGET_CONTROL, data.control.brightslide, GET_VALUE=bright bright=bright*(zoom^0.5)*0.75 makegreyscaleimage, img, x, y, z, nx,ny,bright if(data.viewtype eq 3)then img=SMOOTH(img,3,/EDGE_TRUNCATE) ccol=255 endif else begin makedotplot, img, x, y, z, nx,ny ccol=2 endelse WIDGET_CONTROL, data.control.grwin, GET_VALUE = win_num WSET, win_num if(N_PARAMS() eq 2)then begin retimg = img return endif ; Mark center of rotation if selected with mouse xc=0.0 yc=0.0 zc=0.0 xct=(xc*cos(thetay)+yc*sin(thetax)-zc*cos(thetax)*sin(thetay))*zoom+winstat.xtrans yct=(yc*cos(thetax)+zc*sin(thetax))*zoom+winstat.ytrans zct=(xc*sin(thetay)+zc*cos(thetax)-yc*sin(thetax)*cos(thetay))*zoom+winstat.ztrans dview=4.0 vxsize=3.0 vysize=vxsize*0.75 invvx=1.0/vxsize invvy=1.0/vysize invdv=1.0/dview xplot = FIX(((xct*dview)/(zct*vxsize)+0.5)*nx) yplot = FIX(((yct*dview)/(zct*vysize)+0.5)*ny) if(xplot gt 6 and xplot lt nx-7 and yplot gt 6 and yplot lt ny-7 and zct gt 0.0)then begin for i=-4,5 do begin img[xplot+i,yplot]=ccol img[xplot+i,yplot+1]=ccol img[xplot,yplot+i]=ccol img[xplot+1,yplot+i]=ccol endfor endif set_plot,"z" device,set_resolution=[data.control.xsize,data.control.ysize] tv,img,0,0 ; Mark any waypoints that have been selected if(data.waypoint.npoints gt 0) then begin xc=data.waypoint.x[0:data.waypoint.npoints-1] yc=data.waypoint.y[0:data.waypoint.npoints-1] zc=data.waypoint.z[0:data.waypoint.npoints-1] if(data.range.selectsize gt 0.0)then begin scl = (1.0/data.range.selectsize)*2.0 xc=(xc-data.range.selectx)*scl yc=(yc-data.range.selecty)*scl zc=(zc-data.range.selectz)*scl endif else begin scl = (1.0/data.range.maxsize)*2.0 xc=(xc-data.range.xc)*scl yc=(yc-data.range.yc)*scl zc=(zc-data.range.zc)*scl endelse xc1=(xc*cos(thetay)+(yc*sin(thetax)-zc*cos(thetax))*sin(thetay))*zoom+winstat.xtrans yc1=(yc*cos(thetax)+zc*sin(thetax))*zoom+winstat.ytrans zc1=(xc*sin(thetay)+(zc*cos(thetax)-yc*sin(thetax))*cos(thetay))*zoom+winstat.ztrans xplot = FIX(((xc1*dview)/(zc1*vxsize)+0.5)*nx) yplot = FIX(((yc1*dview)/(zc1*vysize)+0.5)*ny) idx = where(xplot gt 0 and xplot lt data.control.xsize and yplot gt 0 and yplot lt data.control.ysize) if(idx[0] ne -1)then begin for i =0,N_ELEMENTS(idx)-1,1 do begin xyouts,xplot[idx[i]],yplot[idx[i]],string(idx[i]+1,"(i3)") endfor endif if(data.waypoint.npoints eq 1) then plot,[xplot[0]],[yplot[0]],/noerase,xstyle=5,ystyle=5,position=[0.,0.,1.,1.],xrange=[0,data.control.xsize-1],yrange=[0,data.control.ysize-1],psym=4 if(data.waypoint.npoints eq 2) then plot,xplot,yplot,/noerase,xstyle=5,ystyle=5,position=[0.,0.,1.,1.],xrange=[0,data.control.xsize-1],yrange=[0,data.control.ysize-1],psym=-4,linestyle=0 if(data.waypoint.npoints gt 2)then begin plot,xplot,yplot,/noerase,xstyle=5,ystyle=5,position=[0.,0.,1.,1.],xrange=[0,data.control.xsize-1],yrange=[0,data.control.ysize-1],psym=4 xp = data.waypoint.x[0:data.waypoint.npoints-1] yp = data.waypoint.y[0:data.waypoint.npoints-1] zp = data.waypoint.z[0:data.waypoint.npoints-1] t = findgen(data.waypoint.npoints)/data.waypoint.npoints tout = findgen((data.waypoint.npoints-1)*20)/(20.0*data.waypoint.npoints) xspline = SPLINE(t,xp,tout,1) yspline = SPLINE(t,yp,tout,1) zspline = SPLINE(t,zp,tout,1) if(data.range.selectsize gt 0.0)then begin scl = (1.0/data.range.selectsize)*2.0 xspline=(xspline-data.range.selectx)*scl yspline=(yspline-data.range.selecty)*scl zspline=(zspline-data.range.selectz)*scl endif else begin scl = (1.0/data.range.maxsize)*2.0 xspline=(xspline-data.range.xc)*scl yspline=(yspline-data.range.yc)*scl zspline=(zspline-data.range.zc)*scl endelse xs1=(xspline*cos(thetay)+(yspline*sin(thetax)-zspline*cos(thetax))*sin(thetay))*zoom+winstat.xtrans ys1=(yspline*cos(thetax)+zspline*sin(thetax))*zoom+winstat.ytrans zs1=(xspline*sin(thetay)+(zspline*cos(thetax)-yspline*sin(thetax))*cos(thetay))*zoom+winstat.ztrans xplot = FIX(((xs1*dview)/(zs1*vxsize)+0.5)*nx) yplot = FIX(((ys1*dview)/(zs1*vysize)+0.5)*ny) plot,xplot,yplot,/noerase,xstyle=5,ystyle=5,position=[0.,0.,1.,1.],xrange=[0,data.control.xsize-1],yrange=[0,data.control.ysize-1] endif endif ; Add redshift if(data.milli.loaded eq 0) then begin if(data.header.boxsize gt 0.0) then begin str = "z = "+string(data.header.redshift,"(1f6.2)") xyouts, 0.01, 0.95, str, /NORMAL endif else begin str = "Time = "+string(data.header.expansion,"(1e10.2)") xyouts, 0.01, 0.95, str, /NORMAL endelse endif img = tvrd() set_plot,"x" WIDGET_CONTROL, data.control.grwin, GET_VALUE = win_num WSET, win_num tv, img, 0, 0 endelse WIDGET_CONTROL, data.control.grwin, SET_UVALUE=winstat, /NO_COPY END pro makestereoimage, img, x, y, z, nx, ny ; colour table with black,red,cyan and white r = [0 ,255,0 ,255] g = [0 ,0 ,255,255] b = [0 ,0 ,255,255] tvlct,r,g,b img=bytarr(nx,ny) dview=4.0 vxsize=3.0 vysize=vxsize*0.75 invvx=1.0/vxsize invvy=1.0/vysize invdv=1.0/dview xplot = FIX((((x+0.075)*dview)/(z*vxsize)+0.5)*nx) yplot = FIX(((y*dview)/(z*vysize)+0.5)*ny) i = where (xplot GT 0 AND xplot LT (nx-1) AND yplot GT 0 AND yplot LT (ny-1) AND z GT 0.0) img=img*0 if(i[0] ne -1) then img(xplot(i),yplot(i))=1 xplot = FIX((((x-0.075)*dview)/(z*vxsize)+0.5)*nx) yplot = FIX(((y*dview)/(z*vysize)+0.5)*ny) i = where (xplot GT 0 AND xplot LT (nx-1) AND yplot GT 0 AND yplot LT (ny-1) AND z GT 0.0) if(i[0] ne -1) then img(xplot(i),yplot(i))=img(xplot(i),yplot(i))+2 end pro makegreyscaleimage, img, x, y, z, nx, ny, bright dview=4.0 vxsize=3.0 vysize=vxsize*0.75 invvx=1.0/vxsize invvy=1.0/vysize invdv=1.0/dview ; xplot=FIX((x/(1.0+z*invdv)*invvx*nx*0.5)+nx*0.5) ; yplot=FIX((y/(1.0+z*invdv)*invvy*ny*0.5)+ny*0.5) xplot = FIX(((x*dview)/(z*vxsize)+0.5)*nx) yplot = FIX(((y*dview)/(z*vysize)+0.5)*ny) i = where (xplot GT 0 AND xplot LT (nx-1) AND yplot GT 0 AND yplot LT (ny-1) AND z GT 0.0) ; img=img*0 ; if(i[0] ne -1) then img(xplot(i),yplot(i))=255 if(i[0] eq -1) then begin img=bytarr(nx,ny) return endif fimg=alog10(hist_2d(xplot(i),yplot(i),min1=0,max1=nx-1,min2=0,max2=ny-1)+1) fimg=fimg*(bright/50.0) i=where(fimg gt 0.) if(i[0] ne -1)then fimg(i)=fimg(i)+1 fimg=temporary(fimg)*64.0 i=where(fimg gt 254.0) if(i[0] ne -1)then fimg(i)=254.0 fimg(0,0:ny-1)=0 fimg(nx-1,0:ny-1)=0 fimg(0:nx-1,0)=0 fimg(0:nx-1,ny-1)=0 img=byte(fimg) ; img=smooth(img,3,/edge_truncate) end pro makedotplot, img, x, y, z, nx, ny img = bytarr(nx,ny) dview=4.0 vxsize=3.0 vysize=vxsize*0.75 invvx=1.0/vxsize invvy=1.0/vysize invdv=1.0/dview xplot = FIX(((x*dview)/(z*vxsize)+0.5)*nx) yplot = FIX(((y*dview)/(z*vysize)+0.5)*ny) i = where (xplot GT 0 AND xplot LT (nx-1) AND yplot GT 0 AND yplot LT (ny-1) AND z GT 0.0) img=img*0 if(i[0] ne -1) then img(xplot(i),yplot(i))=1 end pro fileprops, top WIDGET_CONTROL, top, GET_UVALUE=data np=data.header.np massarr=data.header.massarr txtarr=STRARR(23) txtarr(1) = ' File: '+data.filename if(data.byteswap eq 0) then txtarr(2) = ' (Byte swapping not required to read this file on this system)' if(data.byteswap eq 1) then txtarr(2) = ' (Byte swapping is required to read this file on this system)' if(data.hdf5 eq 1) then txtarr(2) = ' (This is a HDF5 file)' txtarr(4) = ' Redshift = '+string(data.header.redshift)+', Expansion = '+string(data.header.expansion) txtarr(6) = ' Number of particles by type:' txtarr(8) = ' Type 0: np = '+string(np(0))+', massarr = '+string(massarr(0)) txtarr(9) = ' Type 1: np = '+string(np(1))+', massarr = '+string(massarr(1)) txtarr(10) = ' Type 2: np = '+string(np(2))+', massarr = '+string(massarr(2)) txtarr(11) = ' Type 3: np = '+string(np(3))+', massarr = '+string(massarr(3)) txtarr(12) = ' Type 4: np = '+string(np(4))+', massarr = '+string(massarr(4)) txtarr(13) = ' Type 5: np = '+string(np(5))+', massarr = '+string(massarr(5)) txtarr(15) = ' Simulation parameters:' txtarr(17) = ' Box size = '+string(data.header.boxsize) txtarr(18) = ' Omega0 = '+string(data.header.omega0)+', omegalambda = '+string(data.header.lambda)+', h0 = '+string(data.header.h0) txtarr(20) = ' Flags:' txtarr(22) = ' StarFormation = '+string(data.header.flagsfr)+', Feedback = '+string(data.header.flagfb)+', Cooling = '+string(data.header.flagcool) data.control.propbase=WIDGET_BASE(TITLE="Gadget file properties",GROUP_LEADER=top) text = WIDGET_TEXT(data.control.propbase,YSIZE=24,XSIZE=80,VALUE=txtarr) WIDGET_CONTROL, data.control.propbase, /REALIZE XMANAGER, 'browser', data.control.propbase, /NO_BLOCK end pro changeispecies, top ; Copy particles of species ispecies into plotx,y,z arrays ; Sample down to ~100,000 if more are present WIDGET_CONTROL, top, GET_UVALUE=data ifirst=0L if(data.ispecies gt 0)then ifirst=LONG(TOTAL(LONG(data.header.np(0:data.ispecies-1)),/DOUBLE)) ilast=ifirst+LONG(data.header.np(data.ispecies))-1L xtemp=(*(data.xptr))(ifirst:ilast) ytemp=(*(data.yptr))(ifirst:ilast) ztemp=(*(data.zptr))(ifirst:ilast) WIDGET_CONTROL,data.control.statusbar,SET_VALUE="Selecting particles to display..." WIDGET_CONTROL, /HOURGLASS idx = indgen(1) if(data.range.selectsize gt 0.0)then begin xmin=data.range.oldselectx-(0.5*data.range.selectsize) ymin=data.range.oldselecty-(0.5*data.range.selectsize) zmin=data.range.oldselectz-(0.5*data.range.selectsize) xmax=data.range.oldselectx+(0.5*data.range.selectsize) ymax=data.range.oldselecty+(0.5*data.range.selectsize) zmax=data.range.oldselectz+(0.5*data.range.selectsize) idx=where(xtemp gt xmin and xtemp lt xmax and ytemp gt ymin and $ ytemp lt ymax and ztemp gt zmin and ztemp lt zmax) if(idx[0] ne -1)then begin xtemp=xtemp(idx) ytemp=ytemp(idx) ztemp=ztemp(idx) endif endif if(idx[0] ne -1)then begin PTR_FREE, data.plotx, data.ploty, data.plotz cx=TOTAL(xtemp)/N_ELEMENTS(xtemp) cy=TOTAL(ytemp)/N_ELEMENTS(ytemp) cz=TOTAL(ztemp)/N_ELEMENTS(ztemp) data.range.xcom=cx data.range.ycom=cy data.range.zcom=cz nump=N_ELEMENTS(xtemp) if(nump gt data.nshow)then begin r=randomu(iseed,nump) fac=float(data.nshow)/float(nump) ind=where(r lt fac) xtemp=xtemp(ind) ytemp=ytemp(ind) ztemp=ztemp(ind) endif if(data.range.selectsize gt 0.0)then begin scl = (1.0/data.range.selectsize)*2.0 xtemp=(xtemp-data.range.selectx)*scl ytemp=(ytemp-data.range.selecty)*scl ztemp=(ztemp-data.range.selectz)*scl endif else begin scl = (1.0/data.range.maxsize)*2.0 xtemp=(xtemp-data.range.xc)*scl ytemp=(ytemp-data.range.yc)*scl ztemp=(ztemp-data.range.zc)*scl endelse nshown=n_elements(xtemp) data.plotx=PTR_NEW(xtemp,/NO_COPY) data.ploty=PTR_NEW(ytemp,/NO_COPY) data.plotz=PTR_NEW(ztemp,/NO_COPY) if(nump gt nshown) then begin WIDGET_CONTROL,data.control.statusbar,SET_VALUE="Region contains "+string(nump)+" particles of which a random sample of "+string(nshown)+" are shown." endif else begin WIDGET_CONTROL,data.control.statusbar,SET_VALUE="Region contains "+string(nump)+" particles." endelse data.oldispecies=data.ispecies WIDGET_CONTROL, top, SET_UVALUE=data if(data.viewtype eq 0 or data.viewtype eq 3)then begin if(total(data.header.np) eq data.header.np(1))then begin loadct, 13 endif else begin if(data.ispecies eq 0)then loadct,3,/SILENT if(data.ispecies eq 1)then loadct,8,/SILENT if(data.ispecies eq 2)then loadct,8,/SILENT if(data.ispecies eq 3)then loadct,8,/SILENT if(data.ispecies eq 4)then loadct,1,/SILENT if(data.ispecies eq 5)then loadct,8,/SILENT endelse endif endif else begin ; No particles, so undo change of ispecies and pop up an error box junk=DIALOG_MESSAGE("This region contains no particles of the requested type!",/ERROR,DIALOG_PARENT=top) data.ispecies=data.oldispecies WIDGET_CONTROL, top, SET_UVALUE=data endelse ; Grey out buttons for species with np=0 WIDGET_CONTROL, data.control.part_0, SENSITIVE=1 WIDGET_CONTROL, data.control.part_1, SENSITIVE=1 WIDGET_CONTROL, data.control.part_2, SENSITIVE=1 WIDGET_CONTROL, data.control.part_3, SENSITIVE=1 WIDGET_CONTROL, data.control.part_4, SENSITIVE=1 WIDGET_CONTROL, data.control.part_5, SENSITIVE=1 if(data.header.np(0) eq 0) then WIDGET_CONTROL, data.control.part_0, SENSITIVE=0 if(data.header.np(1) eq 0) then WIDGET_CONTROL, data.control.part_1, SENSITIVE=0 if(data.header.np(2) eq 0) then WIDGET_CONTROL, data.control.part_2, SENSITIVE=0 if(data.header.np(3) eq 0) then WIDGET_CONTROL, data.control.part_3, SENSITIVE=0 if(data.header.np(4) eq 0) then WIDGET_CONTROL, data.control.part_4, SENSITIVE=0 if(data.header.np(5) eq 0) then WIDGET_CONTROL, data.control.part_5, SENSITIVE=0 end pro draw_event, ev ; ; Event handler for draw area ; ; Allow rotation about y-axis and scaling ; by clicking and dragging in the view area. ; ; This routine is called for mouse press/release events, ; mouse motion events and when the visibility of the draw ; area changes. ; WIDGET_CONTROL,ev.top,GET_UVALUE=data ; Don't do anything if no data loaded if(data.loaded gt 0)then begin ; Redraw window if covered then exposed again if(ev.type eq 4) then redraw,ev.top ; Keep track of whether each button is pressed if(ev.type eq 0)then begin bt=ev.press if(bt ge 4) then data.dragstat.button3=1 if(bt ge 4)then bt=bt-4 if(bt eq 1 or bt eq 3)then data.dragstat.button1=1 if(bt eq 2 or bt eq 3)then data.dragstat.button2=1 if(bt eq 2)then data.dragstat.moved2=0 endif if(ev.type eq 1)then begin bt=ev.release if(bt ge 4) then data.dragstat.button3=0 if(bt ge 4)then bt=bt-4 if(bt eq 1 or bt eq 3)then data.dragstat.button1=0 if(bt eq 2 or bt eq 3)then data.dragstat.button2=0 if(bt eq 2 and data.dragstat.moved2 eq 0) then begin locate_object, ev WIDGET_CONTROL,ev.top,GET_UVALUE=data data.dragstat.button2=0 endif endif ; Compare previous to current mouse position to detect dragging ; (only if button is held down) if(ev.type eq 2)then begin if(data.dragstat.button2 eq 1)then data.dragstat.moved2 = 1 if(data.dragstat.button3 eq 1)then begin if(data.dragstat.lastx1 gt -999)then begin dx=ev.x-data.dragstat.lastx1 dy=ev.y-data.dragstat.lasty1 WIDGET_CONTROL,data.control.grwin,GET_UVALUE=winstat WIDGET_CONTROL,data.control.yrotslide,GET_VALUE=yrot winstat.xtrans=winstat.xtrans+float(dx)*0.01 winstat.ytrans=winstat.ytrans+float(dy)*0.01 WIDGET_CONTROL,data.control.yrotslide,SET_VALUE=yrot WIDGET_CONTROL,data.control.grwin,SET_UVALUE=winstat redraw,ev.top endif data.dragstat.lastx1=ev.x data.dragstat.lasty1=ev.y endif else begin data.dragstat.lastx1=-1000 endelse if(data.dragstat.button1 eq 1)then begin if(data.dragstat.lastx2 gt -999)then begin dx=ev.x-data.dragstat.lastx2 dy=ev.y-data.dragstat.lasty2 WIDGET_CONTROL,data.control.grwin,GET_UVALUE=winstat WIDGET_CONTROL,data.control.yrotslide,GET_VALUE=yrot WIDGET_CONTROL,data.control.zoomslide,GET_VALUE=zoom ;winstat.ztrans=winstat.ztrans+float(dy)*0.01 yrot=yrot+float(dx)*0.3 zoom=zoom-float(dy)*0.3 if(yrot lt 0.0)then begin yrot=yrot+360.0 endif else begin if(yrot gt 360.0) then yrot=yrot-360.0 endelse WIDGET_CONTROL,data.control.yrotslide,SET_VALUE=yrot WIDGET_CONTROL,data.control.grwin,SET_UVALUE=winstat WIDGET_CONTROL,data.control.zoomslide,SET_VALUE=zoom redraw,ev.top endif data.dragstat.lastx2=ev.x data.dragstat.lasty2=ev.y endif else begin data.dragstat.lastx2=-1000 endelse if(data.dragstat.button2 eq 1 and data.dragstat.moved2 eq 1 and data.waypoint.npoints gt 0)then begin move_waypoint,data,ev.x,ev.y WIDGET_CONTROL,ev.top,SET_UVALUE=data redraw, ev.top endif endif WIDGET_CONTROL,ev.top,SET_UVALUE=data endif end pro move_waypoint,data,mousex,mousey ; Find coordinates of waypoints on the screen WIDGET_CONTROL, data.control.grwin, GET_UVALUE=winstat WIDGET_CONTROL, data.control.xrotslide, GET_VALUE=xrot WIDGET_CONTROL, data.control.yrotslide, GET_VALUE=yrot WIDGET_CONTROL, data.control.zoomslide, GET_VALUE=zoom dview=4.0 vxsize=3.0 vysize=vxsize*0.75 invvx=1.0/vxsize invvy=1.0/vysize invdv=1.0/dview nx=data.control.xsize ny=data.control.ysize zoom=zoomfac(zoom) thetay=DOUBLE(yrot/180.0*3.14159) thetax=DOUBLE(xrot/180.0*3.14159) xc=data.waypoint.x[0:data.waypoint.npoints-1] yc=data.waypoint.y[0:data.waypoint.npoints-1] zc=data.waypoint.z[0:data.waypoint.npoints-1] if(data.range.selectsize gt 0.0)then begin scl = (1.0/data.range.selectsize)*2.0 xc=(xc-data.range.selectx)*scl yc=(yc-data.range.selecty)*scl zc=(zc-data.range.selectz)*scl endif else begin scl = (1.0/data.range.maxsize)*2.0 xc=(xc-data.range.xc)*scl yc=(yc-data.range.yc)*scl zc=(zc-data.range.zc)*scl endelse xc1=(xc*cos(thetay)+(yc*sin(thetax)-zc*cos(thetax))*sin(thetay))*zoom+winstat.xtrans yc1=(yc*cos(thetax)+zc*sin(thetax))*zoom+winstat.ytrans zc1=(xc*sin(thetay)+(zc*cos(thetax)-yc*sin(thetax))*cos(thetay))*zoom+winstat.ztrans xplot = FIX(((xc1*dview)/(zc1*vxsize)+0.5)*nx) yplot = FIX(((yc1*dview)/(zc1*vysize)+0.5)*ny) r = ((mousex-xplot)*(mousex-xplot) + (mousey-yplot)*(mousey-yplot)) idx = sort(r) if(r[idx[0]] lt 500.0) then begin ipoint = idx[0] zselect = zc1[idx[0]] xselect = (float(mousex)/float(nx)-0.5)*zselect*vxsize/dview yselect = (float(mousey)/float(ny)-0.5)*zselect*vysize/dview xselect = (xselect-winstat.xtrans)/zoom yselect = (yselect-winstat.ytrans)/zoom zselect = (zselect-winstat.ztrans)/zoom xs = xselect*cos(-thetay) - zselect*sin(-thetay) ys = yselect*cos(-thetax) + (xselect*sin(-thetay)+zselect*cos(-thetay))*sin(-thetax) zs = -yselect*sin(-thetax)+ (xselect*sin(-thetay)+zselect*cos(-thetay))*cos(-thetax) if(data.range.selectsize gt 0.0)then begin scl = (1.0/data.range.selectsize)*2.0 xs=(xs/scl+data.range.selectx) ys=(ys/scl+data.range.selecty) zs=(zs/scl+data.range.selectz) endif else begin scl = (1.0/data.range.maxsize)*2.0 xs=(xs/scl+data.range.xc) ys=(ys/scl+data.range.yc) zs=(zs/scl+data.range.zc) endelse data.waypoint.x[ipoint] = xs data.waypoint.y[ipoint] = ys data.waypoint.z[ipoint] = zs endif end pro edit_waypoints, top WIDGET_CONTROL,top,GET_UVALUE=data if(data.waypoint.npoints eq 0) then return data.control.waypt_dialog.base=WIDGET_BASE(TITLE='Edit Waypoints',/COLUMN,GROUP_LEADER=top) waypt_label = WIDGET_LABEL(data.control.waypt_dialog.base,VALUE="Select waypoint to edit:") waypt_selectbase = WIDGET_BASE(data.control.waypt_dialog.base,/ROW,/ALIGN_CENTER) waypt_prev = WIDGET_BUTTON(waypt_selectbase,VALUE=" < ",UVALUE="PREVWP") data.control.waypt_dialog.select = WIDGET_TEXT(waypt_selectbase,VALUE=" 1",UVALUE="CURRWP") waypt_next = WIDGET_BUTTON(waypt_selectbase,VALUE=" > ",UVALUE="NEXTWP") xc = data.waypoint.x[0] yc = data.waypoint.y[0] zc = data.waypoint.z[0] vxc = data.waypoint.vx[0] vyc = data.waypoint.vy[0] vzc = data.waypoint.vz[0] poslabel = WIDGET_LABEL(data.control.waypt_dialog.base,VALUE="Coordinates of this point") posbase = WIDGET_BASE(data.control.waypt_dialog.base,/ROW,/ALIGN_CENTER) data.control.waypt_dialog.xfield = CW_FIELD(posbase,TITLE="x:",VALUE=xc,/FLOATING,/ROW,XSIZE=8,/RETURN_EVENTS,UVALUE="XENTRY") data.control.waypt_dialog.yfield = CW_FIELD(posbase,TITLE="y:",VALUE=yc,/FLOATING,/ROW,XSIZE=8,/RETURN_EVENTS,UVALUE="YENTRY") data.control.waypt_dialog.zfield = CW_FIELD(posbase,TITLE="z:",VALUE=zc,/FLOATING,/ROW,XSIZE=8,/RETURN_EVENTS,UVALUE="ZENTRY") ; viewlabel = WIDGET_LABEL(data.control.waypt_dialog.base,VALUE="View direction from this point") ; viewbase = WIDGET_BASE(data.control.waypt_dialog.base,/ROW,/ALIGN_CENTER) ; data.control.waypt_dialog.vxfield = CW_FIELD(viewbase,TITLE="x:",VALUE=vxc,/NOEDIT,/ROW,XSIZE=8) ; data.control.waypt_dialog.vyfield = CW_FIELD(viewbase,TITLE="y:",VALUE=vyc,/NOEDIT,/ROW,XSIZE=8) ; data.control.waypt_dialog.vzfield = CW_FIELD(viewbase,TITLE="z:",VALUE=vzc,/NOEDIT,/ROW,XSIZE=8) buttonbase = WIDGET_BASE(data.control.waypt_dialog.base,/COLUMN,/ALIGN_CENTER) ; data.control.waypt_dialog.selectpt = WIDGET_BUTTON(buttonbase,VALUE=" Point view towards selected point ",UVALUE="SELECTEDPT") ; data.control.waypt_dialog.nextpt = WIDGET_BUTTON(buttonbase,VALUE=" Point view towards next waypoint (default) ",UVALUE="NEXTPT") data.control.waypt_dialog.delete = WIDGET_BUTTON(buttonbase,VALUE="Delete this waypoint",UVALUE="DELETE") data.control.waypt_dialog.ok = WIDGET_BUTTON(buttonbase,VALUE="Close window",UVALUE="OK") WIDGET_CONTROL,top,SET_UVALUE=data WIDGET_CONTROL,data.control.waypt_dialog.base,SET_UVALUE=top WIDGET_CONTROL,data.control.waypt_dialog.base, /REALIZE XMANAGER, 'edit_waypoints',data.control.waypt_dialog.base, /NO_BLOCK end pro edit_waypoints_event, ev WIDGET_CONTROL, ev.top, GET_UVALUE=base WIDGET_CONTROL, base, GET_UVALUE=data WIDGET_CONTROL, ev.id, GET_UVALUE = uv if(uv eq "OK")then WIDGET_CONTROL, ev.top, /DESTROY if(uv eq "NEXTWP")then begin WIDGET_CONTROL,data.control.waypt_dialog.select,GET_VALUE=str ipoint = LONG(str) ipoint = ipoint[0]+1 if(ipoint gt data.waypoint.npoints)then ipoint=data.waypoint.npoints WIDGET_CONTROL, data.control.waypt_dialog.xfield, SET_VALUE=data.waypoint.x[ipoint-1] WIDGET_CONTROL, data.control.waypt_dialog.yfield, SET_VALUE=data.waypoint.y[ipoint-1] WIDGET_CONTROL, data.control.waypt_dialog.zfield, SET_VALUE=data.waypoint.z[ipoint-1] ;WIDGET_CONTROL, data.control.waypt_dialog.vxfield, SET_VALUE=data.waypoint.vx[ipoint-1] ;WIDGET_CONTROL, data.control.waypt_dialog.vyfield, SET_VALUE=data.waypoint.vy[ipoint-1] ;WIDGET_CONTROL, data.control.waypt_dialog.vzfield, SET_VALUE=data.waypoint.vz[ipoint-1] WIDGET_CONTROL,data.control.waypt_dialog.select,SET_VALUE=string(ipoint,"(1i3)") endif if(uv eq "PREVWP")then begin WIDGET_CONTROL,data.control.waypt_dialog.select,GET_VALUE=str ipoint = LONG(str) ipoint = ipoint[0] - 1 if(ipoint lt 1)then ipoint=1 WIDGET_CONTROL, data.control.waypt_dialog.xfield, SET_VALUE=data.waypoint.x[ipoint-1] WIDGET_CONTROL, data.control.waypt_dialog.yfield, SET_VALUE=data.waypoint.y[ipoint-1] WIDGET_CONTROL, data.control.waypt_dialog.zfield, SET_VALUE=data.waypoint.z[ipoint-1] ;WIDGET_CONTROL, data.control.waypt_dialog.vxfield, SET_VALUE=data.waypoint.vx[ipoint-1] ;WIDGET_CONTROL, data.control.waypt_dialog.vyfield, SET_VALUE=data.waypoint.vy[ipoint-1] ;WIDGET_CONTROL, data.control.waypt_dialog.vzfield, SET_VALUE=data.waypoint.vz[ipoint-1] WIDGET_CONTROL,data.control.waypt_dialog.select,SET_VALUE=string(ipoint,"(1i3)") endif if(uv eq "DELETE")then begin WIDGET_CONTROL,data.control.waypt_dialog.select,GET_VALUE=str ipoint = LONG(str) ipoint = ipoint[0] - 1 if(ipoint eq data.waypoint.npoints-1)then begin data.waypoint.npoints=data.waypoint.npoints-1 endif else begin data.waypoint.x[ipoint:data.waypoint.npoints-2]=data.waypoint.x[ipoint+1:data.waypoint.npoints-1] data.waypoint.y[ipoint:data.waypoint.npoints-2]=data.waypoint.y[ipoint+1:data.waypoint.npoints-1] data.waypoint.z[ipoint:data.waypoint.npoints-2]=data.waypoint.z[ipoint+1:data.waypoint.npoints-1] data.waypoint.vx[ipoint:data.waypoint.npoints-2]=data.waypoint.vx[ipoint+1:data.waypoint.npoints-1] data.waypoint.vy[ipoint:data.waypoint.npoints-2]=data.waypoint.vy[ipoint+1:data.waypoint.npoints-1] data.waypoint.vz[ipoint:data.waypoint.npoints-2]=data.waypoint.vz[ipoint+1:data.waypoint.npoints-1] data.waypoint.npoints=data.waypoint.npoints-1 endelse WIDGET_CONTROL, base, SET_UVALUE=data redraw, base if(data.waypoint.npoints eq 0)then begin WIDGET_CONTROL,ev.top,/DESTROY return endif ipoint = 1 WIDGET_CONTROL, data.control.waypt_dialog.xfield, SET_VALUE=data.waypoint.x[ipoint-1] WIDGET_CONTROL, data.control.waypt_dialog.yfield, SET_VALUE=data.waypoint.y[ipoint-1] WIDGET_CONTROL, data.control.waypt_dialog.zfield, SET_VALUE=data.waypoint.z[ipoint-1] ;WIDGET_CONTROL, data.control.waypt_dialog.vxfield, SET_VALUE=data.waypoint.vx[ipoint-1] ;WIDGET_CONTROL, data.control.waypt_dialog.vyfield, SET_VALUE=data.waypoint.vy[ipoint-1] ;WIDGET_CONTROL, data.control.waypt_dialog.vzfield, SET_VALUE=data.waypoint.vz[ipoint-1] WIDGET_CONTROL, data.control.waypt_dialog.select, SET_VALUE=" 1" endif if(uv eq "SELECTEDPT") then begin WIDGET_CONTROL,data.control.waypt_dialog.select,GET_VALUE=str ipoint = LONG(str) ipoint = ipoint[0] - 1 dx = data.range.selectx - data.waypoint.x[ipoint] dy = data.range.selecty - data.waypoint.y[ipoint] dz = data.range.selectz - data.waypoint.z[ipoint] r = sqrt(dx*dx+dy*dy+dz*dz) dx=dx/r dy=dy/r dz=dz/r data.waypoint.vx[ipoint] = dx data.waypoint.vy[ipoint] = dy data.waypoint.vz[ipoint] = dz WIDGET_CONTROL,base,SET_UVALUE=data ;WIDGET_CONTROL, data.control.waypt_dialog.vxfield, SET_VALUE=data.waypoint.vx[ipoint] ;WIDGET_CONTROL, data.control.waypt_dialog.vyfield, SET_VALUE=data.waypoint.vy[ipoint] ;WIDGET_CONTROL, data.control.waypt_dialog.vzfield, SET_VALUE=data.waypoint.vz[ipoint] endif if(uv eq "NEXTPT") then begin WIDGET_CONTROL,data.control.waypt_dialog.select,GET_VALUE=str ipoint = LONG(str) ipoint = ipoint[0] - 1 data.waypoint.vx[ipoint] = 0.0 data.waypoint.vy[ipoint] = 0.0 data.waypoint.vz[ipoint] = 0.0 ;WIDGET_CONTROL, data.control.waypt_dialog.vxfield, SET_VALUE=data.waypoint.vx[ipoint] ;WIDGET_CONTROL, data.control.waypt_dialog.vyfield, SET_VALUE=data.waypoint.vy[ipoint] ;WIDGET_CONTROL, data.control.waypt_dialog.vzfield, SET_VALUE=data.waypoint.vz[ipoint] endif if(uv eq "XENTRY") then begin WIDGET_CONTROL,data.control.waypt_dialog.select,GET_VALUE=str ipoint = LONG(str) ipoint = ipoint[0] - 1 WIDGET_CONTROL,ev.id,GET_VALUE=str data.waypoint.x[ipoint] = float(str) WIDGET_CONTROL,base,SET_UVALUE=data redraw, base endif if(uv eq "YENTRY") then begin WIDGET_CONTROL,data.control.waypt_dialog.select,GET_VALUE=str ipoint = LONG(str) ipoint = ipoint[0] - 1 WIDGET_CONTROL,ev.id,GET_VALUE=str data.waypoint.y[ipoint] = float(str) WIDGET_CONTROL,base,SET_UVALUE=data redraw, base endif if(uv eq "ZENTRY") then begin WIDGET_CONTROL,data.control.waypt_dialog.select,GET_VALUE=str ipoint = LONG(str) ipoint = ipoint[0] - 1 WIDGET_CONTROL,ev.id,GET_VALUE=str data.waypoint.z[ipoint] = float(str) WIDGET_CONTROL,base,SET_UVALUE=data redraw, base endif end pro region_select, top WIDGET_CONTROL,top,GET_UVALUE=data ; Define select region dialog selectbase=WIDGET_BASE(TITLE='Select Region',/COLUMN,/MODAL,GROUP_LEADER=top) select_label = WIDGET_LABEL(selectbase,VALUE="Enter coordinates and size region to view") coordbase=WIDGET_BASE(selectbase,/ROW) xbase=WIDGET_BASE(coordbase,/COLUMN) ybase=WIDGET_BASE(coordbase,/COLUMN) zbase=WIDGET_BASE(coordbase,/COLUMN) sizebase=WIDGET_BASE(selectbase,/COLUMN) xcoordlabel = WIDGET_LABEL(xbase,VALUE="X:") ycoordlabel = WIDGET_LABEL(ybase,VALUE="Y:") zcoordlabel = WIDGET_LABEL(zbase,VALUE="Z:") sizelabel = WIDGET_LABEL(sizebase,VALUE="Cube side length:") xcoordentry = WIDGET_TEXT(xbase,/EDITABLE,XSIZE=10,UVALUE='XENTRY',VALUE='0') ycoordentry = WIDGET_TEXT(ybase,/EDITABLE,XSIZE=10,UVALUE='YENTRY',VALUE='0') zcoordentry = WIDGET_TEXT(zbase,/EDITABLE,XSIZE=10,UVALUE='ZENTRY',VALUE='0') sizeentry = WIDGET_TEXT(sizebase,/EDITABLE,XSIZE=10,UVALUE='SIZEENTRY',VALUE='0') cofmbutton = WIDGET_BUTTON(selectbase,VALUE="Use center of current selection",UVALUE="COFM") cofrotbutton = WIDGET_BUTTON(selectbase,VALUE="Use center of rotation (the cross)",UVALUE="COFROT") buttonbase = WIDGET_BASE(selectbase,/ROW) okbutton = WIDGET_BUTTON(buttonbase,VALUE=" View Region ",UVALUE="SELECTOK") allbutton= WIDGET_BUTTON(buttonbase, VALUE=" View All ",UVALUE="SELECTALL") cancelbutton= WIDGET_BUTTON(buttonbase,VALUE=" Cancel ",UVALUE="SELECTCANCEL") select_dialog=CREATE_STRUCT("selectbase",selectbase,"xcoordentry", $ xcoordentry,"ycoordentry",ycoordentry, $ "zcoordentry",zcoordentry,"sizeentry",sizeentry) data.control.select_dialog=select_dialog WIDGET_CONTROL,selectbase,DEFAULT_BUTTON=okbutton WIDGET_CONTROL,selectbase,CANCEL_BUTTON=cancelbutton WIDGET_CONTROL,top,SET_UVALUE=data WIDGET_CONTROL,data.control.select_dialog.selectbase, SET_UVALUE=top if(data.range.selectsize gt 0)then begin cx=data.range.selectx cy=data.range.selecty cz=data.range.selectz endif else begin cx=data.range.xc cy=data.range.yc cz=data.range.zc endelse WIDGET_CONTROL, data.control.select_dialog.xcoordentry,SET_VALUE=string(cx,format="(f10.4)") WIDGET_CONTROL, data.control.select_dialog.ycoordentry,SET_VALUE=string(cy,format="(f10.4)") WIDGET_CONTROL, data.control.select_dialog.zcoordentry,SET_VALUE=string(cz,format="(f10.4)") WIDGET_CONTROL,data.control.select_dialog.selectbase, /REALIZE XMANAGER, 'region_select',data.control.select_dialog.selectbase, /NO_BLOCK end ; Event handler for the select region dialog box pro region_select_event, ev WIDGET_CONTROL, ev.id, GET_UVALUE = uv if(uv eq 'SELECTCANCEL') then WIDGET_CONTROL,ev.top,/DESTROY if(uv eq 'SELECTOK') then begin WIDGET_CONTROL, ev.top, GET_UVALUE=base WIDGET_CONTROL, base, GET_UVALUE=data WIDGET_CONTROL, data.control.select_dialog.xcoordentry,GET_VALUE=xtext WIDGET_CONTROL, data.control.select_dialog.ycoordentry,GET_VALUE=ytext WIDGET_CONTROL, data.control.select_dialog.zcoordentry,GET_VALUE=ztext WIDGET_CONTROL, data.control.select_dialog.sizeentry,GET_VALUE=sizetext data.range.selectx=float(xtext) data.range.selecty=float(ytext) data.range.selectz=float(ztext) data.range.oldselectx=float(xtext) data.range.oldselecty=float(ytext) data.range.oldselectz=float(ztext) data.range.selectsize=float(sizetext) WIDGET_CONTROL,data.control.grwin,GET_UVALUE=winstat winstat.xtrans=0.0 winstat.ytrans=0.0 winstat.ztrans=6.0 WIDGET_CONTROL,data.control.grwin,SET_UVALUE=winstat WIDGET_CONTROL,data.control.yrotslide,SET_VALUE=180 WIDGET_CONTROL,data.control.zoomslide,SET_VALUE=50 WIDGET_CONTROL, base, SET_UVALUE=data WIDGET_CONTROL,ev.top,/DESTROY changeispecies, base endif if(uv eq 'SELECTALL') then begin WIDGET_CONTROL, ev.top, GET_UVALUE=base WIDGET_CONTROL, base, GET_UVALUE=data data.range.selectx=0.0 data.range.selecty=0.0 data.range.selectz=0.0 data.range.selectsize=0.0 data.range.oldselectx=data.range.xc data.range.oldselecty=data.range.yc data.range.oldselectz=data.range.zc WIDGET_CONTROL,data.control.grwin,GET_UVALUE=winstat winstat.xtrans=0.0 winstat.ytrans=0.0 winstat.ztrans=6.0 WIDGET_CONTROL,data.control.grwin,SET_UVALUE=winstat WIDGET_CONTROL,data.control.yrotslide,SET_VALUE=180 WIDGET_CONTROL,data.control.zoomslide,SET_VALUE=50 WIDGET_CONTROL, base, SET_UVALUE=data WIDGET_CONTROL,ev.top,/DESTROY changeispecies, base endif if(uv eq 'COFM') then begin WIDGET_CONTROL, ev.top, GET_UVALUE=base WIDGET_CONTROL, base, GET_UVALUE=data cx=data.range.oldselectx cy=data.range.oldselecty cz=data.range.oldselectz WIDGET_CONTROL, data.control.select_dialog.xcoordentry,SET_VALUE=string(cx,format="(f10.4)") WIDGET_CONTROL, data.control.select_dialog.ycoordentry,SET_VALUE=string(cy,format="(f10.4)") WIDGET_CONTROL, data.control.select_dialog.zcoordentry,SET_VALUE=string(cz,format="(f10.4)") endif if(uv eq 'COFROT') then begin WIDGET_CONTROL, ev.top, GET_UVALUE=base WIDGET_CONTROL, base, GET_UVALUE=data if(data.range.selectsize gt 0)then begin cx=data.range.selectx cy=data.range.selecty cz=data.range.selectz endif else begin cx=data.range.xc cy=data.range.yc cz=data.range.zc endelse WIDGET_CONTROL, data.control.select_dialog.xcoordentry,SET_VALUE=string(cx,format="(f10.4)") WIDGET_CONTROL, data.control.select_dialog.ycoordentry,SET_VALUE=string(cy,format="(f10.4)") WIDGET_CONTROL, data.control.select_dialog.zcoordentry,SET_VALUE=string(cz,format="(f10.4)") endif end pro locate_object,ev ; ; Set the centre of rotation to the median coordinates of particles ; nearby on the screen to the point that was clicked ; WIDGET_CONTROL, ev.top, GET_UVALUE=data WIDGET_CONTROL, data.control.grwin, GET_UVALUE=winstat WIDGET_CONTROL, data.control.xrotslide, GET_VALUE=xrot WIDGET_CONTROL, data.control.yrotslide, GET_VALUE=yrot WIDGET_CONTROL, data.control.zoomslide, GET_VALUE=zoom nx=data.control.xsize ny=data.control.ysize zoom=zoomfac(zoom) thetay=DOUBLE(yrot/180.0*3.14159) thetax=DOUBLE(xrot/180.0*3.14159) x=(*(data.plotx)*cos(thetay)+(*(data.ploty)*sin(thetax)-*(data.plotz)*cos(thetax))*sin(thetay))*zoom+winstat.xtrans y=(*(data.ploty)*cos(thetax)+*(data.plotz)*sin(thetax))*zoom+winstat.ytrans z=(*(data.plotx)*sin(thetay)+(*(data.plotz)*cos(thetax)-*(data.ploty)*sin(thetax))*cos(thetay))*zoom+winstat.ztrans xmouse = ev.x ymouse = ev.y dview=4.0 vxsize=3.0 vysize=vxsize*0.75 invvx=1.0/vxsize invvy=1.0/vysize invdv=1.0/dview xplot = FIX(((x*dview)/(z*vxsize)+0.5)*nx) yplot = FIX(((y*dview)/(z*vysize)+0.5)*ny) idx=where(xplot gt xmouse-10 and xplot lt xmouse+10 and yplot gt ymouse-10 and yplot lt ymouse+10) if(idx[0] ne -1)then begin ; Retrieve un-rotated coordinates x=*(data.plotx) y=*(data.ploty) z=*(data.plotz) ; Transform back to original coordinate system if(data.range.selectsize gt 0.0)then begin scl = 1.0/((1.0/data.range.selectsize)*2.0) x=(x*scl)+data.range.selectx y=(y*scl)+data.range.selecty z=(z*scl)+data.range.selectz endif else begin scl = 1.0/((1.0/data.range.maxsize)*2.0) x=(x*scl)+data.range.xc y=(y*scl)+data.range.yc z=(z*scl)+data.range.zc endelse ; Center on median of coordinates of nearby particles xc=median(x(idx)) yc=median(y(idx)) zc=median(z(idx)) WIDGET_CONTROL,data.control.statusbar,SET_VALUE="Selected new center of rotation: "+string(xc)+", "+string(yc)+", "+string(zc) if(data.range.selectsize eq 0)then begin data.range.selectsize=data.range.maxsize endif data.range.selectx=xc data.range.selecty=yc data.range.selectz=zc scl = (1.0/data.range.selectsize)*2.0 x=(x-data.range.selectx)*scl y=(y-data.range.selecty)*scl z=(z-data.range.selectz)*scl winstat.xtrans=0.0 winstat.ytrans=0.0 WIDGET_CONTROL, data.control.grwin, SET_UVALUE=winstat *(data.plotx)=x *(data.ploty)=y *(data.plotz)=z WIDGET_CONTROL, ev.top, SET_UVALUE=data redraw,ev.top endif end pro read_milli_region_event, ev ; Max number of particles that can be read from Millennium sim ; - should find a way to dynamically allocate this really! npmax=40000000L WIDGET_CONTROL, ev.id, GET_UVALUE = uv if(uv eq 'MILLICANCEL') then WIDGET_CONTROL,ev.top,/DESTROY if(uv eq 'MILLIOK') then begin WIDGET_CONTROL, /HOURGLASS WIDGET_CONTROL, ev.top, GET_UVALUE=base WIDGET_CONTROL, base, GET_UVALUE=data WIDGET_CONTROL, data.control.milli_dialog.xcoordentry,GET_VALUE=xtext WIDGET_CONTROL, data.control.milli_dialog.ycoordentry,GET_VALUE=ytext WIDGET_CONTROL, data.control.milli_dialog.zcoordentry,GET_VALUE=ztext WIDGET_CONTROL, data.control.milli_dialog.sizeentry,GET_VALUE=sizetext WIDGET_CONTROL, data.control.milli_dialog.snapentry,GET_VALUE=snaptext if(float(sizetext) le 50.0 and float(sizetext) ge 2.0 $ and float(xtext) ge 0.0 and float(xtext) le 500.0 $ and float(ytext) ge 0.0 and float(ytext) le 500.0 $ and float(ztext) ge 0.0 and float(ztext) le 500.0 $ and long(snaptext) ge 10 and long(snaptext) le 63 $ ) then begin WIDGET_CONTROL, data.control.evol_movie, SENSITIVE=0 xmin = float(xtext)-float(sizetext)*0.5 xmax = float(xtext)+float(sizetext)*0.5 ymin = float(ytext)-float(sizetext)*0.5 ymax = float(ytext)+float(sizetext)*0.5 zmin = float(ztext)-float(sizetext)*0.5 zmax = float(ztext)+float(sizetext)*0.5 isnap = long(snaptext) data.milli.xmin = xmin data.milli.xmax = xmax data.milli.ymin = ymin data.milli.ymax = ymax data.milli.zmin = zmin data.milli.zmax = zmax data.milli.loaded = 1 WIDGET_CONTROL,ev.top,/DESTROY if(data.loaded gt 0)then begin ptr_free,data.xptr ptr_free,data.yptr ptr_free,data.zptr endif x=fltarr(npmax) y=fltarr(npmax) z=fltarr(npmax) WIDGET_CONTROL, data.control.setsnap, SET_VALUE=isnap npart=0L zred=0.0 WIDGET_CONTROL,data.control.statusbar,SET_VALUE="Reading millennium data..." ierr = CALL_EXTERNAL( $ "/home/jch/IDL/GadgetViewer/idl_read_region.so", $ "idl_read_region",isnap,xmin,xmax,ymin,ymax, $ zmin,zmax,npart,x,y,z,npmax,/I_VALUE) xrange = MAX(x)-MIN(x) yrange = MAX(y)-MIN(y) zrange = MAX(z)-MIN(z) data.range.maxsize = MAX([xrange,yrange,zrange]) data.range.xc = TOTAL(x(0:npart-1))/npart data.range.yc = TOTAL(y(0:npart-1))/npart data.range.zc = TOTAL(z(0:npart-1))/npart data.range.oldselectx=data.range.xc data.range.oldselecty=data.range.yc data.range.oldselectz=data.range.zc data.loaded=1 data.xptr=PTR_NEW(x,/NO_COPY) data.yptr=PTR_NEW(y,/NO_COPY) data.zptr=PTR_NEW(z,/NO_COPY) data.ispecies=1 data.range.selectsize=0.0 data.header.omega0=0.25 data.header.lambda=0.75 data.header.massarr=data.header.massarr*0.0 data.header.massarr(1)=8.60657e-2 data.header.h0=0.73 data.header.np(0:5)=0 data.header.np(1)=npart data.header.boxsize=500.0 data.header.expansion=double(1.0/(1.0+zred)) data.header.redshift=double(zred) data.filename='Millennium data for snapshot '+string(isnap,format="(1i3.3)") data.hdf5 = 0 WIDGET_CONTROL, base, SET_UVALUE=data ; Update plotx,y,z arrays and redraw image changeispecies, base redraw, base ; Grey out buttons for species with np=0 WIDGET_CONTROL, data.control.part_0, SENSITIVE=0 WIDGET_CONTROL, data.control.part_1, SENSITIVE=1 WIDGET_CONTROL, data.control.part_2, SENSITIVE=0 WIDGET_CONTROL, data.control.part_3, SENSITIVE=0 WIDGET_CONTROL, data.control.part_4, SENSITIVE=0 WIDGET_CONTROL, data.control.part_5, SENSITIVE=0 ; Enable menu options now we have some data WIDGET_CONTROL,data.control.file_prop,SENSITIVE=1 WIDGET_CONTROL,data.control.part_menu,SENSITIVE=1 WIDGET_CONTROL,data.control.view_menu,SENSITIVE=1 WIDGET_CONTROL,data.control.file_write,SENSITIVE=1 WIDGET_CONTROL,data.control.viewscheme,SENSITIVE=1 WIDGET_CONTROL,data.control.makeimage,SENSITIVE=1 WIDGET_CONTROL,data.control.file_export,SENSITIVE=1 WIDGET_CONTROL,data.control.waypoint_menu,SENSITIVE=1 endif else begin if(float(sizetext) gt 50.0) then junk=DIALOG_MESSAGE("Size must be less than 50Mpc/h!",/ERROR,DIALOG_PARENT=ev.top) if(float(sizetext) lt 2.0) then junk=DIALOG_MESSAGE("Size must be more than 2Mpc/h!",/ERROR,DIALOG_PARENT=ev.top) if(long(snaptext) lt 10 or long(snaptext) gt 63) then junk=DIALOG_MESSAGE("Snapshot number must be in range 10-63!",/ERROR,DIALOG_PARENT=ev.top) if(float(sizetext) ge 2.0 and float(sizetext) le 50.0 and long(snaptext) ge 10 and long(snaptext) le 63)then junk=DIALOG_MESSAGE("Coordinates must be in range 0-500Mpc/h!",/ERROR,DIALOG_PARENT=ev.top) endelse endif end pro read_milli_region, top WIDGET_CONTROL,top,GET_UVALUE=data ; Define select region dialog millibase=WIDGET_BASE(TITLE='Read Millennium Region',/COLUMN,/MODAL,GROUP_LEADER=top) milli_label = WIDGET_LABEL(millibase,VALUE=" Enter coordinates and size of region to read: ") snapbase=WIDGET_BASE(millibase,/ROW,/ALIGN_CENTER) snaplabel = WIDGET_LABEL(snapbase,VALUE=" Snapshot (7-63): ") snapentry = WIDGET_TEXT(snapbase,/EDITABLE,XSIZE=10,UVALUE='SNAPENTRY',VALUE='63') coordbase=WIDGET_BASE(millibase,/ROW,/ALIGN_CENTER) xbase=WIDGET_BASE(coordbase,/COLUMN) ybase=WIDGET_BASE(coordbase,/COLUMN) zbase=WIDGET_BASE(coordbase,/COLUMN) sizebase=WIDGET_BASE(millibase,/ROW,/ALIGN_CENTER) xcoordlabel = WIDGET_LABEL(xbase,VALUE="X:") ycoordlabel = WIDGET_LABEL(ybase,VALUE="Y:") zcoordlabel = WIDGET_LABEL(zbase,VALUE="Z:") sizelabel = WIDGET_LABEL(sizebase,VALUE="Cube side length:") xcoordentry = WIDGET_TEXT(xbase,/EDITABLE,XSIZE=10,UVALUE='XENTRY',VALUE='0') ycoordentry = WIDGET_TEXT(ybase,/EDITABLE,XSIZE=10,UVALUE='YENTRY',VALUE='0') zcoordentry = WIDGET_TEXT(zbase,/EDITABLE,XSIZE=10,UVALUE='ZENTRY',VALUE='0') sizeentry = WIDGET_TEXT(sizebase,/EDITABLE,XSIZE=10,UVALUE='SIZEENTRY',VALUE='0') buttonbase = WIDGET_BASE(millibase,/ROW,/ALIGN_CENTER) okbutton = WIDGET_BUTTON(buttonbase,VALUE=" Read data ",UVALUE="MILLIOK") cancelbutton= WIDGET_BUTTON(buttonbase,VALUE=" Cancel ",UVALUE="MILLICANCEL") milli_dialog=CREATE_STRUCT("millibase",millibase,"xcoordentry", $ xcoordentry,"ycoordentry",ycoordentry, $ "zcoordentry",zcoordentry,"sizeentry",sizeentry,$ "snapentry",snapentry) data.control.milli_dialog=milli_dialog WIDGET_CONTROL,millibase,DEFAULT_BUTTON=okbutton WIDGET_CONTROL,millibase,CANCEL_BUTTON=cancelbutton WIDGET_CONTROL,top,SET_UVALUE=data WIDGET_CONTROL,data.control.milli_dialog.millibase, SET_UVALUE=top if(data.range.selectsize gt 0)then begin cx=data.range.selectx cy=data.range.selecty cz=data.range.selectz endif else begin cx=data.range.xc cy=data.range.yc cz=data.range.zc endelse WIDGET_CONTROL,data.control.milli_dialog.millibase, /REALIZE XMANAGER, 'read_milli_region',data.control.milli_dialog.millibase, /NO_BLOCK end pro write_ascii, top WIDGET_CONTROL,top,GET_UVALUE=data filename = DIALOG_PICKFILE(DIALOG_PARENT=top,PATH=data.path,/WRITE,GET_PATH=path) if(filename ne '')then begin check_file, filename, path, iwrite, top if(iwrite eq 0) then return WIDGET_CONTROL, /HOURGLASS ifirst=0L if(data.ispecies gt 0)then ifirst=LONG(TOTAL(LONG(data.header.np(0:data.ispecies-1)))) ilast=ifirst+LONG(data.header.np(data.ispecies))-1L if(data.range.selectsize gt 0.0)then begin xmin=data.range.oldselectx-0.5*data.range.selectsize xmax=data.range.oldselectx+0.5*data.range.selectsize ymin=data.range.oldselecty-0.5*data.range.selectsize ymax=data.range.oldselecty+0.5*data.range.selectsize zmin=data.range.oldselectz-0.5*data.range.selectsize zmax=data.range.oldselectz+0.5*data.range.selectsize idx =where((*(data.xptr))(ifirst:ilast) gt xmin and (*(data.xptr))(ifirst:ilast) lt xmax $ and (*(data.yptr))(ifirst:ilast) gt ymin and (*(data.yptr))(ifirst:ilast) lt ymax $ and (*(data.zptr))(ifirst:ilast) gt zmin and (*(data.xptr))(ifirst:ilast) lt zmax) xtemp=(*(data.xptr))(ifirst:ilast) ytemp=(*(data.yptr))(ifirst:ilast) ztemp=(*(data.zptr))(ifirst:ilast) xtemp=xtemp(idx) ytemp=ytemp(idx) ztemp=ztemp(idx) endif else begin xtemp=(*(data.xptr))(ifirst:ilast) ytemp=(*(data.yptr))(ifirst:ilast) ztemp=(*(data.zptr))(ifirst:ilast) endelse np=N_ELEMENTS(xtemp) if(DIALOG_MESSAGE("This will write "+string(np)+" particles to the file. Continue?",/QUESTION,DIALOG_PARENT=top) eq 'Yes')then begin WIDGET_CONTROL, data.control.statusbar, SET_VALUE=" Writing particle coordinates to file..." openw,lun,filename,/GET_LUN printf,lun,np,FORMAT="(1i16)" i=0L for i=0L,np-1L,1L do begin printf,lun,xtemp[i],ytemp[i],ztemp[i],FORMAT="(3e16.8)" endfor free_lun,lun WIDGET_CONTROL, data.control.statusbar, SET_VALUE=" Finished writing file." endif endif end pro makejpegimage, top WIDGET_CONTROL,top,GET_UVALUE=data filename = DIALOG_PICKFILE(DIALOG_PARENT=top,PATH=data.path,/WRITE,GET_PATH=path) if(filename ne '')then begin check_file, filename, path, iwrite, top if(iwrite eq 0) then return WIDGET_CONTROL, /HOURGLASS redraw,top,retimg tvlct,r,g,b,/GET nx=data.control.xsize ny=data.control.ysize outimg = bytarr(3,nx,ny) outimg(0,*,*)=r(retimg) outimg(1,*,*)=g(retimg) outimg(2,*,*)=b(retimg) write_jpeg,filename,outimg,true=1,quality=100 WIDGET_CONTROL, data.control.statusbar, SET_VALUE=" Finished writing image." endif end pro export_coords, top WIDGET_CONTROL, top, GET_UVALUE=data ifirst=0L if(data.ispecies gt 0)then ifirst=LONG(TOTAL(LONG(data.header.np(0:data.ispecies-1)))) ilast=ifirst+LONG(data.header.np(data.ispecies))-1L if(data.range.selectsize gt 0.0)then begin xmin=data.range.oldselectx-0.5*data.range.selectsize xmax=data.range.oldselectx+0.5*data.range.selectsize ymin=data.range.oldselecty-0.5*data.range.selectsize ymax=data.range.oldselecty+0.5*data.range.selectsize zmin=data.range.oldselectz-0.5*data.range.selectsize zmax=data.range.oldselectz+0.5*data.range.selectsize idx =where((*(data.xptr))(ifirst:ilast) gt xmin and (*(data.xptr))(ifirst:ilast) lt xmax $ and (*(data.yptr))(ifirst:ilast) gt ymin and (*(data.yptr))(ifirst:ilast) lt ymax $ and (*(data.zptr))(ifirst:ilast) gt zmin and (*(data.xptr))(ifirst:ilast) lt zmax) xtemp=(*(data.xptr))(ifirst:ilast) ytemp=(*(data.yptr))(ifirst:ilast) ztemp=(*(data.zptr))(ifirst:ilast) xtemp=xtemp(idx) ytemp=ytemp(idx) ztemp=ztemp(idx) endif else begin xtemp=(*(data.xptr))(ifirst:ilast) ytemp=(*(data.yptr))(ifirst:ilast) ztemp=(*(data.zptr))(ifirst:ilast) endelse np=N_ELEMENTS(xtemp) DEFSYSV, "!GadgetX",xtemp DEFSYSV, "!GadgetY",ytemp DEFSYSV, "!GadgetZ",ztemp junk=DIALOG_MESSAGE("Coordinates should now be available in IDL as !GadgetX,!GadgetY,!GadgetZ",/INFORMATION,DIALOG_PARENT=top) end pro check_file, fname, path, iwrite, top ; Make sure file fname can be written to ; First check directory is writeable iwrite = file_test(path,/write,/directory) if(iwrite eq 0) then begin junk = DIALOG_MESSAGE("You don't have write permission for that directory!", /ERROR, DIALOG_PARENT=top) return endif iwrite = file_test(fname) ; If file exists make sure its writable if(iwrite eq 1) then begin iwrite = file_test(fname,/WRITE) if(iwrite eq 0) then begin junk = DIALOG_MESSAGE("You don't have write permission for that file!", /ERROR, DIALOG_PARENT=top) return endif endif else begin ; If it doesn't exist we're ok iwrite=1 endelse end ; Dummy function so it will compile without HDF5 support ; If HDF5 is here it will override this function H5_GET_LIBVERSION return, 0 end ; ; Main program - creates main window and registers it with the ; xmanager when run. ; pro gadgetviewer set_plot, "X" base=WIDGET_BASE(TITLE='Gadget File Viewer',/COLUMN,MBAR=menubar,/TLB_SIZE_EVENTS) file_menu = WIDGET_BUTTON(menubar, VALUE='File', /MENU) file_open = WIDGET_BUTTON(file_menu,VALUE='Open binary Gadget file..',UVALUE='OPEN') file_open_hdf5 = WIDGET_BUTTON(file_menu,VALUE='Open HDF5 Gadget file..',UVALUE='OPEN_HDF5') file_prop = WIDGET_BUTTON(file_menu,VALUE='Gadget file properties..',UVALUE='PROPS') milli_region = WIDGET_BUTTON(file_menu, VALUE='Read Millennium data...', UVALUE='READREGION',/SEPARATOR) file_write = WIDGET_BUTTON(file_menu, VALUE='Write coordinates to ascii file...', UVALUE='WRITEASCII',/SEPARATOR) file_export = WIDGET_BUTTON(file_menu, VALUE='Export coordinates to IDL', UVALUE='EXPORT') makeimage = WIDGET_BUTTON(file_menu,VALUE='Write JPEG...',UVALUE='MAKEIMAGE') file_exit = WIDGET_BUTTON(file_menu,VALUE='Exit',UVALUE='EXIT',/SEPARATOR) part_menu = WIDGET_BUTTON(menubar, VALUE='Particles', /MENU) part_0 = WIDGET_BUTTON(part_menu, VALUE='Type 0 - Gas', UVALUE='SPECIES0') part_1 = WIDGET_BUTTON(part_menu, VALUE='Type 1 - DM', UVALUE='SPECIES1') part_2 = WIDGET_BUTTON(part_menu, VALUE='Type 2 - Boundary', UVALUE='SPECIES2') part_3 = WIDGET_BUTTON(part_menu, VALUE='Type 3 - Boundary', UVALUE='SPECIES3') part_4 = WIDGET_BUTTON(part_menu, VALUE='Type 4 - Stars', UVALUE='SPECIES4') part_5 = WIDGET_BUTTON(part_menu, VALUE='Type 5 - Unused?', UVALUE='SPECIES5') view_menu = WIDGET_BUTTON(menubar, VALUE='View', /MENU) selectregion = WIDGET_BUTTON(view_menu, VALUE='Select region...', UVALUE='SELECTREGION') resetview = WIDGET_BUTTON(view_menu, VALUE='Reset view', UVALUE='RESET',/SEPARATOR) viewgrey = WIDGET_BUTTON(view_menu, VALUE='Colour by 2D particle density', UVALUE='GREY',/SEPARATOR) viewgrey = WIDGET_BUTTON(view_menu, VALUE='Colour by 2D density and smooth', UVALUE='GREYSMOOTH') viewmono = WIDGET_BUTTON(view_menu, VALUE='Black and white dotplot', UVALUE='MONO') viewstereo = WIDGET_BUTTON(view_menu, VALUE='Red/Cyan Anaglyph', UVALUE='STEREO') viewmin = WIDGET_BUTTON(view_menu, VALUE='Show up to 50,000 particles', UVALUE='VIEWMIN',/SEPARATOR) viewmed = WIDGET_BUTTON(view_menu, VALUE='Show up to 100,000 particles', UVALUE='VIEWMED') viewmax = WIDGET_BUTTON(view_menu, VALUE='Show up to 200,000 particles', UVALUE='VIEWHIGH') viewmax = WIDGET_BUTTON(view_menu, VALUE='Show up to 500,000 particles', UVALUE='VIEWMAX') viewscheme = WIDGET_BUTTON(view_menu, VALUE='Change color scheme...', UVALUE='COLSCHEME',/SEPARATOR) waypoint_menu = WIDGET_BUTTON(menubar, VALUE='Movie', /MENU) rot_movie = WIDGET_BUTTON(waypoint_menu, VALUE='Rotation...', UVALUE='ROTMOVIE') path_movie=WIDGET_BUTTON(waypoint_menu,VALUE='Flythrough...',UVALUE='PATHMOVIE') evol_movie=WIDGET_BUTTON(waypoint_menu,VALUE='Evolving...',UVALUE='EVOLMOVIE') waypoint_add = WIDGET_BUTTON(waypoint_menu, VALUE='Add waypoint here', UVALUE='ADDWAYPOINT',/SEPARATOR) waypoint_edit = WIDGET_BUTTON(waypoint_menu, VALUE='Edit waypoints...', UVALUE='EDITWAYPOINTS') waypoint_clear = WIDGET_BUTTON(waypoint_menu, VALUE='Clear all waypoints', UVALUE='CLEARWAYPOINTS') waypoint_write = WIDGET_BUTTON(waypoint_menu, VALUE='Write waypoints to file', UVALUE='WRITEWAYPOINTS') helpmenu = WIDGET_BUTTON(menubar, VALUE='Help', /MENU,/ALIGN_RIGHT) helpcontrols = WIDGET_BUTTON(helpmenu, VALUE='Controls...',UVALUE="HELPCONTROLS") helpversion = WIDGET_BUTTON(helpmenu, VALUE='Version...',UVALUE="HELPVERSION") sidepanel=WIDGET_BASE(base,/ROW) dragstat = CREATE_STRUCT("lastx1",0.0,"lasty1",0.0,"lastx2",0.0,"lasty2",0.0,"button1",0,"button2",0,"button3",0,"moved2",0) grwin = WIDGET_DRAW(sidepanel, UVALUE = 0,GRAPHICS_LEVEL=1,XSIZE=640,YSIZE=480,RETAIN=0,EVENT_PRO="draw_event",/BUTTON_EVENTS,/MOTION_EVENTS,/EXPOSE_EVENTS) xrotslide = WIDGET_SLIDER(sidepanel,VALUE=180,MINIMUM=0,MAXIMUM=360,UVALUE='XRSLIDER',/SUPPRESS_VALUE,TITLE='',/DRAG,/VERTICAL,YSIZE=300) statusbar =WIDGET_TEXT(base,VALUE="Status bar") lowerpanel=WIDGET_BASE(base,/ROW) snappanel = WIDGET_BASE(lowerpanel, /COLUMN,/ALIGN_CENTER,/GRID_LAYOUT) setsnap = CW_FIELD(snappanel,TITLE="Snapshot no.:",VALUE=0,/INTEGER,XSIZE=4,/RETURN_EVENTS,UVALUE="SETSNAP") nextbase = WIDGET_BASE(snappanel,/ROW,/ALIGN_CENTER) prevsnap = WIDGET_BUTTON(nextbase,VALUE=' Prev ',UVALUE='PREVSNAP',/ALIGN_CENTER) nextsnap = WIDGET_BUTTON(nextbase,VALUE=' Next ',UVALUE='NEXTSNAP',/ALIGN_CENTER) slidepanel=WIDGET_BASE(lowerpanel,/COLUMN) yrotslide = WIDGET_SLIDER(slidepanel,VALUE=180,MINIMUM=0,MAXIMUM=360,UVALUE='YRSLIDER',/SUPPRESS_VALUE,TITLE='Rotation',/DRAG,XSIZE=300) zoomslide = WIDGET_SLIDER(slidepanel,VALUE=50,MINIMUM=0,MAXIMUM=500,UVALUE='ZOOMSLIDER',/SUPPRESS_VALUE,TITLE='Scale',/DRAG,XSIZE=300) ;movepanel = WIDGET_BASE(lowerpanel, /COLUMN,/ALIGN_CENTER) ;up = WIDGET_BUTTON(movepanel,VALUE=' Up ',UVALUE='UP',/ALIGN_CENTER) ;lrpanel = WIDGET_BASE(movepanel,/ROW) ;left = WIDGET_BUTTON(lrpanel,VALUE=' Left ',UVALUE='LEFT') ;right = WIDGET_BUTTON(lrpanel,VALUE='Right ',UVALUE='RIGHT') ;down = WIDGET_BUTTON(movepanel,VALUE=' Down ',UVALUE='DOWN',/ALIGN_CENTER) fwdpanel = WIDGET_BASE(lowerpanel, /COLUMN,/ALIGN_RIGHT,/GRID_LAYOUT) brightslide = WIDGET_SLIDER(fwdpanel,VALUE=50,MINIMUM=0,MAXIMUM=100,UVALUE='BRIGHTSLIDER',/SUPPRESS_VALUE,TITLE='Brightness',/ALIGN_CENTER,/DRAG) fwdbase = WIDGET_BASE(fwdpanel,/ROW) forward = WIDGET_BUTTON(fwdbase,VALUE=' Fwd ',UVALUE='FWD') backward = WIDGET_BUTTON(fwdbase,VALUE=' Back ',UVALUE='BACK') ; Placeholder for select_region dialog widget IDs select_dialog=CREATE_STRUCT("selectbase",base,"xcoordentry", $ base,"ycoordentry",base, $ "zcoordentry",base,"sizeentry",base) milli_dialog=CREATE_STRUCT("millibase",base,"xcoordentry", $ base,"ycoordentry",base, $ "zcoordentry",base,"sizeentry",base,"snapentry",base) waypt_dialog=CREATE_STRUCT("select",base,"base",base,"xfield",base,"yfield",base,"zfield",base,"vxfield",base,"vyfield",base,"vzfield",base,"selectpt",base,"nextpt",base,"delete",base,"ok",base) ; Realize the widget (i.e., display it on screen): WIDGET_CONTROL, base, /REALIZE XMANAGER, 'browser', base, /NO_BLOCK propbase=WIDGET_BASE(TITLE="Properties") text = WIDGET_TEXT(propbase,YSIZE=20,XSIZE=80,VALUE="Text") ; Set up a structure to store the data xptr=PTR_NEW() yptr=PTR_NEW() zptr=PTR_NEW() plotx=PTR_NEW() ploty=PTR_NEW() plotz=PTR_NEW() milli = CREATE_STRUCT("xmin",0.0,"xmax",0.0,"ymin",0.0,"ymax",0.0,"zmin",0.0,"zmax",0.0,"loaded",0) header = CREATE_STRUCT("np",lindgen(6),"massarr",dindgen(6),"expansion",DOUBLE(-1.0),"redshift",DOUBLE(-1),"flagsfr",0L,"flagfb",0L,"nall",lindgen(6),"flagcool",0L,"nfiles",0L,"boxsize",DOUBLE(-1),"omega0",DOUBLE(0.0),"lambda",DOUBLE(0.0),"h0",DOUBLE(0.0)) control=CREATE_STRUCT("grwin",grwin,"xrotslide",xrotslide,"yrotslide",yrotslide,"zoomslide",zoomslide,"part_0",part_0,"part_1",part_1,"part_2",part_2,"part_3",part_3,"part_4",part_4,"part_5",part_5,"propbase",propbase,"select_dialog",select_dialog,"file_prop",file_prop,"part_menu",part_menu,"view_menu",view_menu,"milli_dialog",milli_dialog,"statusbar",statusbar,"xsize",640,"ysize",480,"file_write",file_write,"viewscheme",viewscheme,"brightslide",brightslide,"makeimage",makeimage,"file_export",file_export,"waypoint_menu",waypoint_menu,"waypt_dialog",waypt_dialog,"setsnap",setsnap,"nextsnap",nextsnap,"prevsnap",prevsnap,"helpmenu",helpmenu,"evol_movie",evol_movie) range = CREATE_STRUCT("xc",0.0,"yc",0.0,"zc",0.0,"maxsize",0.0,"selectx",0.0,"selecty",0.0,"selectz",0.0,"selectsize",0.0,"xcom",0.0,"ycom",0.0,"zcom",0.0,"oldselectx",0.0,"oldselecty",0.0,"oldselectz",0.0) waypoint = CREATE_STRUCT("x",fltarr(100),"y",fltarr(100),"z",fltarr(100),"npoints",0,"vx",fltarr(100),"vy",fltarr(100),"vz",fltarr(100)) data = CREATE_STRUCT("header",header,"xptr",xptr,"yptr",yptr,"zptr",zptr,"control",control,"loaded",0,"ispecies",1,'filename','none','byteswap',0,"plotx",plotx,"ploty",ploty,"plotz",plotz,"path","./","viewtype",0,"range",range,"dragstat",dragstat,"nshow",100000L,"panelheight",0L,"oldispecies",0,"waypoint",waypoint,"hdf5",0,"milli",milli) winstat = CREATE_STRUCT("xtrans",0.0,"ytrans",0.0,"ztrans",6.0) WIDGET_CONTROL, grwin, SET_UVALUE = winstat WIDGET_CONTROL,file_prop,SENSITIVE=0 WIDGET_CONTROL,part_menu,SENSITIVE=0 WIDGET_CONTROL,view_menu,SENSITIVE=0 WIDGET_CONTROL,file_write,SENSITIVE=0 WIDGET_CONTROL,makeimage,SENSITIVE=0 WIDGET_CONTROL,file_export,SENSITIVE=0 WIDGET_CONTROL,data.control.viewscheme,SENSITIVE=0 WIDGET_CONTROL,data.control.waypoint_menu,SENSITIVE=0 WIDGET_CONTROL,statusbar,SET_VALUE="No data loaded." ; Millennium data is only available on titania so grey out option elsewhere if (getenv("HOST") ne 'titania')then begin WIDGET_CONTROL,milli_region,SENSITIVE=0 str1 = "Running on "+getenv("HOST")+": Millennium data not available here. " endif else begin str1 = "Running on "+getenv("HOST")+": Millennium data is available. " endelse WIDGET_CONTROL, data.control.grwin, GET_VALUE = win_num WSET, win_num loadct,13,/SILENT WIDGET_CONTROL,base,TLB_GET_SIZE=basesize data.panelheight=basesize(1)-data.control.ysize WIDGET_CONTROL, data.control.xrotslide, YSIZE=data.control.ysize WIDGET_CONTROL, data.control.yrotslide, XSIZE=data.control.xsize*0.5 WIDGET_CONTROL, data.control.zoomslide, XSIZE=data.control.xsize*0.5 WIDGET_CONTROL, data.control.xrotslide, SCR_YSIZE=data.control.ysize WIDGET_CONTROL, data.control.yrotslide, SCR_XSIZE=data.control.xsize*0.5 WIDGET_CONTROL, data.control.zoomslide, SCR_XSIZE=data.control.xsize*0.5 WIDGET_CONTROL, base, SET_UVALUE = data ; Check if we have HDF5 support x = ROUTINE_INFO(/SYSTEM) i = where(x eq "H5_OPEN") if(i[0] eq -1) then begin WIDGET_CONTROL, file_open_hdf5, SENSITIVE=0 str2 = "IDL HDF5 routines not found." endif else begin str2 = "Found HDF5 version "+H5_GET_LIBVERSION()+"." endelse WIDGET_CONTROL, statusbar, SET_VALUE= (str1+str2) end