From 33e2f4887cf229b62d23924a0a33e56167f32f62 Mon Sep 17 00:00:00 2001 From: Shawn <22651173+AquaDragonTRS@users.noreply.github.com> Date: Tue, 7 May 2019 13:45:36 -0700 Subject: [PATCH] Updated respository Added 3 new files currently in circulation, and the updated 3302/3305 files. --- HDF5/check_devices.pro | 66 ++++ HDF5/lapd_ni_xyz_configuration.pro | 551 ++++++++++++++++++++++++++++ HDF5/lapd_sis3302_configuration.pro | 82 +++-- HDF5/lapd_sis3305_configuration.pro | 18 +- HDF5/read_lapd_data_newsis_ver4.pro | 475 ++++++++++++++++++++++++ 5 files changed, 1149 insertions(+), 43 deletions(-) create mode 100644 HDF5/check_devices.pro create mode 100644 HDF5/lapd_ni_xyz_configuration.pro create mode 100644 HDF5/read_lapd_data_newsis_ver4.pro diff --git a/HDF5/check_devices.pro b/HDF5/check_devices.pro new file mode 100644 index 0000000..c6c84b7 --- /dev/null +++ b/HDF5/check_devices.pro @@ -0,0 +1,66 @@ +;NAME: check_devices.pro +;AUTHOR: Steve Vincena / swjtang +;DATE: 16 Aug 2018 +;DESCRIPTION: Returns an array after checking if a device is being used from within the datafile. +;SYNTAX: Result = CHECK_DEVICES(input_file) +;CHANGELOG: Oct 04, 2017 => (swjtang) Added NI_XZ as a check-able device +; Oct 16, 2017 => (") Added SIS board type as an additional condition to check for an active device. +; Aug 16, 2018 => (") Added NI_XYZ as a check-able device + +FUNCTION CHECK_DEVICES, input_file + +devices = ['6K Compumotor','SIS crate','SIS 3302','SIS 3305','SIS 3301','n5700','NI_XZ','NI_XYZ'] +ndevices = n_elements(devices) +check_devices = {name:devices, active:fltarr(ndevices)} + +;;;; OPEN .HDF5 FILE ------------------------------------------------------------------------------ +IF (input_file EQ '') THEN GOTO, Cleanup + +IF (FILE_TEST(input_file) EQ 1) THEN BEGIN + ;;;; CREATE THE OBJECT ---------------------------------------------------- + HDF5_file = OBJ_NEW('HDF5_file') + HDF5_file->Open, input_file +ENDIF ELSE GOTO, Cleanup + +;;;; OPEN RAW DATA AND CONFIGURATION GROUP -------------------------------------------------------- +rac_group = HDF5_file->Open_group('Raw data + config') +rac_subgroup_names = rac_group->Read_group_names() + +;;;; READ GROUP NAMES TO DETERMINE IF A DEVICE IS PRESENT ----------------------------------------- +FOR idevice=0, ndevices-1 DO BEGIN + device_test = WHERE(rac_subgroup_names EQ devices[idevice]) + IF ( device_test NE -1 ) THEN check_devices.active[idevice] = 1 +ENDFOR + +;;;; CHECK FOR FAST OR SLOW DIGITIZERS ON SIS CRATE ----------------------------------------------- +IF check_devices.active[1] THEN BEGIN + siscrate = rac_group->Open_group('SIS crate') + siscrate_config_names = siscrate->Read_group_names() + FOR iconfig=0, n_elements(siscrate_config_names)-1 DO BEGIN + siscrate_subgroup = siscrate->open_group(siscrate_config_names[iconfig]) + siscrate_subgroup_names = siscrate_subgroup->Read_group_names() + FOR idevice=0, ndevices-1 DO BEGIN + siscrate_test = WHERE(strmid(siscrate_subgroup_names,0,21) EQ 'SIS crate ' $ + +strmid(devices[idevice],4,strlen(devices[idevice])-1)+' config') + IF ( siscrate_test[0] NE -1 ) THEN BEGIN + sis_board_types = siscrate_subgroup->Read_attribute('SIS crate board types') + sis3302_board_indices = where(sis_board_types eq 2) + sis3305_board_indices = where(sis_board_types eq 3) + CASE devices[idevice] OF + 'SIS 3302': IF (sis3302_board_indices[0] NE -1) THEN check_devices.active[idevice] = 1 + 'SIS 3305': IF (sis3305_board_indices[0] NE -1) THEN check_devices.active[idevice] = 1 + ELSE: check_devices.active[idevice] = 1 + ENDCASE + ENDIF + ENDFOR + ENDFOR + OBJ_DESTROY, siscrate_subgroup + OBJ_DESTROY, siscrate +ENDIF + +OBJ_DESTROY, rac_group +OBJ_DESTROY, hdf5_file + +Cleanup: +RETURN, check_devices +END diff --git a/HDF5/lapd_ni_xyz_configuration.pro b/HDF5/lapd_ni_xyz_configuration.pro new file mode 100644 index 0000000..7f4771f --- /dev/null +++ b/HDF5/lapd_ni_xyz_configuration.pro @@ -0,0 +1,551 @@ +;NAME: lapd_ni_xyz_configuration.pro (adapted from lapd_ni_xz_configuration.pro) +;AUTHOR: KKrynski / swjtang +;DATE: 04 Sep 2018 +;DESCRIPTION: Returns an IDL structure containing the parsed information in the 'NI_XYZ' group of an LAPD HDF5 file +;SYNTAX: Result = LAPD_NI_XYZ_CONFIGURATION(input_file, motionid=motionid) +;CHANGELOG: +;04 Sep 2018 => Checks if the total number of points matches the intended number of +; of points. If it does not, return 'incomplete' geometry. +;Oct 17, 2018 => Added 'quiet' option to suppress non-critical print outputs. (not yet checked) + +FUNCTION LAPD_NI_XYZ_CONFIGURATION, input_file, motion=motionid, quiet=quiet +COMPILE_OPT IDL2 + +;;;; ASSIGN DEFAULT VALUES FOR UNSPECIFIED GEOMETRY ----------------------------------------------- +geometry='Unknown' +nx = ulong(1) & ny = ulong(1) & nz = ulong(1) & nr = ulong(1) +nwrites = ulong(1) +xvec=fltarr(nx) & yvec=fltarr(ny) & zvec=fltarr(nz) & rvec=fltarr(nr) +xval=float(0.) & yval=float(0.) & zval=float(0.) & rval=float(0.) +xyz = fltarr(3,nx,ny,nz) +xyzr= fltarr(4,nx,ny,nz,nr) +xar= fltarr(nx,ny,nz) & yar=fltarr(nx,ny,nz) & zar=fltarr(nx,ny,nz) & rar=fltarr(nx,ny,nz) +mlist = {x:float(0.), y:float(0.), z:float(0.), r:float(0.), nwrites:float(1)} +r_unique = float([0.]) +p_unique = ["Unknown"] + +;;;; OPEN .HDF5 FILE ------------------------------------------------------------------------------ +IF (input_file EQ '') THEN BEGIN + input_file='' + input_file=dialog_pickfile() +ENDIF +IF (input_file EQ '') THEN BEGIN + out_message='Error associated with input file' + GOTO, CLEANUP +ENDIF + +;;;; CREATE THE OBJECT ---------------------------------------------------------------------------- +HDF5_file = OBJ_NEW('HDF5_file') +IF (FILE_TEST(input_file) EQ 1) THEN BEGIN + print,'--------------------------------------------------' + print, 'Opening: ', input_file + HDF5_file->Open, input_file +ENDIF + +;;;; DETERMINE LAPD SOFTWARE VERSION -------------------------------------------------------------- +sw_version = HDF5_file.Read_attribute('LaPD HDF5 software version') +IF quiet EQ 0 THEN print,'LaPD HDF5 software version = '+sw_version + +;;;; OPEN RAW DATA AND CONFIGURATION GROUP -------------------------------------------------------- +rac_group = HDF5_file.Open_group('Raw data + config') +rac_subgroup_names = rac_group.Read_group_names() +OBJ_DESTROY, rac_group + +;;;; PROCESS NI_XYZ IF IT EXISTS ------------------------------------------------------------------- +motion_group_test = WHERE(rac_subgroup_names EQ 'NI_XYZ') +IF (motion_group_test[0] NE -1) THEN BEGIN + + motion_group_name= '/Raw data + config/NI_XYZ' + + motion_group= HDF5_file.Open_group(motion_group_name) + motion_subgroup_names= motion_group.Read_group_names() + motion_dataset_names = motion_group.Read_dataset_names() + IF quiet EQ 0 THEN BEGIN + print, 'Motion dataset names:' + counter=1 + PM, '#'+strtrim(counter++,1)+': ', motion_dataset_names + ENDIF + + ;;; PROCESS NI_XYZ RUNTIME LIST ---------------------------------------------------------------- + ; Open Runtime list of positions and angles at every shot number + ; If there is a NI_XYZ group, there must be a Runtime List. No error check here + + CASE sw_version OF + '1.1': BEGIN + motion_rtl_dataset = HDF5_file.Read_dataset(motion_group_name+'/Run time list') + END + ; With the introduction of the real-time-translator (sw_version 1.2), + ; each probe gets its own dataset of probe motions. + ; For now (10/22/2012) just grab the first one and re-use version 1.1 code <---------- this.... + ELSE: BEGIN ;assume version 1.2 or compatible + IF keyword_set(motionid) THEN ind=motionid ELSE ind=0 ;changable index so we can use other probe motion lists + IF quiet EQ 0 THEN print, ' -> Chosen motion dataset: #', strtrim(ind+1,1) + motion_rtl_dataset = motion_group.Read_dataset(motion_dataset_names[ind]) + END + ENDCASE + + xyz_motion_shot_number = reform(ulong64(motion_rtl_dataset._DATA.SHOT_NUMBER)) + xyz_motion_xlist = reform(float(motion_rtl_dataset._DATA.X)) + xyz_motion_ylist = reform(float(motion_rtl_dataset._DATA.Y)) + xyz_motion_zlist = reform(float(motion_rtl_dataset._DATA.Z)) + xyz_motion_rlist = reform(float(motion_rtl_dataset._DATA.R)) + xyz_motion_thetalist = reform(float(motion_rtl_dataset._DATA.THETA)) + xyz_motion_philist = reform(float(motion_rtl_dataset._DATA.PHI)) + xyz_motion_config_name = reform(motion_rtl_dataset._DATA.CONFIGURATION_NAME) + + ;???? do we really need the following??? + n_motion_lists=n_elements(uniq(xyz_motion_config_name,sort(xyz_motion_config_name))) + n_probes=n_motion_lists + + ; r_unique = fltarr(n_probes) + ; p_unique = strarr(n_probes) + ; FOR i=0, n_probes-1 DO BEGIN + ; r_unique[i] = xz_motion_rlist[i] + ; p_unique[i] = xz_motion_config_name[i] + ; ENDFOR + + IF (n_probes GT 1) THEN BEGIN + PRINT,'Warning in --- LAPD_NI_XYZ_CONFIGURATION.pro ----' + PRINT,'More than one probe found. Program will assume that all probes are moving on the same grid!' + PRINT,'In the position arrays, the z location will be fixed to the first probe position listed.' ;;;;;;<---???????? + ; PRINT,'The tag "r_unique" in the motion list structure will contain the unique z locations' + ; PRINT,'The tag "p_unique" in the motion list structure will contain the corresponding probe names' + ; FOR i=0, n_probes-1 do begin + ; PRINT,strcompress('z location of probe, '+p_unique[i] +' is '+string(r_unique[i])+ ' cm') + ; ENDFOR + ;;;; CLENSE INPUTS + n_probes = 1 + one_probe_index = WHERE(xyz_motion_config_name EQ xyz_motion_config_name[0]) + xyz_motion_shot_number = xyz_motion_shot_number[one_probe_index] + xyz_motion_xlist = xyz_motion_xlist[one_probe_index] + xyz_motion_ylist = xyz_motion_ylist[one_probe_index] + xyz_motion_zlist = xyz_motion_zlist[one_probe_index] + xyz_motion_rlist = xyz_motion_rlist[one_probe_index] + xyz_motion_thetalist = xyz_motion_thetalist[one_probe_index] + xyz_motion_philist = xyz_motion_philist[one_probe_index] + xyz_motion_config_name = xyz_motion_config_name[one_probe_index] + ENDIF + + IF ( (n_motion_lists GT 1) OR (n_probes GT 1) ) THEN BEGIN + PRINT,'Warning: this program cannot properly parse coordinate information when a datarun'+ $ + ' has multiple motion lists or multiple probes moving with the same motion list.' + PRINT,'...' + PRINT,'Dividing the apparent number of writes by the number of motion lists in the hopes'+ $ + ' that this will solve the problem.' + ENDIF + ;-------------done with runtime list ------------ + + ;;;; there are only motion lists in the subgroup + motion_list_indexes=where(motion_subgroup_names);strmid(motion_subgroup_names,0,1) eq 'p') + IF (motion_list_indexes[0] eq -1) THEN BEGIN + print,'!!! NI_XYZ group exists, but no probes / motion lists found.' + goto, no_motion_lists + ENDIF ELSE BEGIN + n_motion_lists = n_elements(motion_list_indexes) + motion_list_names=motion_subgroup_names[motion_list_indexes] + ENDELSE + + IF quiet EQ 0 THEN BEGIN + print, '--------------------------------------------------' + print,'All probes & motion lists found in this datarun:' + FOR i_motion_list=0L, n_motion_lists-1 DO BEGIN + current_motion_list = motion_list_names[i_motion_list] + + motion_list_group = motion_group->Open_group(current_motion_list) + probe_name = motion_list_group->Read_attribute('probe_name') + print, '#', strtrim(i_motion_list+1,1),': ', current_motion_list+' / '+probe_name + ENDFOR + print, '--------------------------------------------------' + ENDIF + + motion_list = motion_list_names[0] + IF quiet EQ 0 THEN print, 'Now choosing the first motion list ('+motion_list+')' + motion_list_group = motion_group->Open_group(motion_list) + + nx = ulong(motion_list_group->Read_attribute('Nx')) + ny = ulong(motion_list_group->Read_attribute('Ny')) + nz = ulong(motion_list_group->Read_attribute('Nz')) + + ml_dx = float(motion_list_group->Read_attribute('dx')) + ml_dy = float(motion_list_group->Read_attribute('dy')) + ml_dz = float(motion_list_group->Read_attribute('dz')) + + ml_x0 = float(motion_list_group->Read_attribute('x0')) + ml_y0 = float(motion_list_group->Read_attribute('y0')) + ml_z0 = float(motion_list_group->Read_attribute('z0')) + + zport = float(motion_list_group->Read_attribute('z_port')) + fanXYZ = motion_list_group->Read_attribute('fan_XYZ') ; if points are on a fanned surface !!!Reads opposite + minZ = float(motion_list_group->Read_attribute('min_zdrive_steps')) + maxZ = float(motion_list_group->Read_attribute('max_zdrive_steps')) + minY = float(motion_list_group->Read_attribute('min_ydrive_steps')) + maxY = float(motion_list_group->Read_attribute('max_ydrive_steps')) + + nxnynz = nx*nz*ny + nwrites = n_elements(xyz_motion_xlist)/nxnynz;/n_probes + + geometry='Unknown' + IF ( (nz GT 1) AND (nx GT 1) AND (ny GT 1) ) THEN geometry='xyz-volume' ;added + IF ( (nz EQ 1) AND (nx GT 1) AND (ny GT 1) ) THEN geometry='xy-plane' ;added + IF ( (nz GT 1) AND (nx GT 1) AND (ny EQ 1) ) THEN geometry='xz-plane' ;adjusted + IF ( (nz GT 1) AND (nx EQ 1) AND (ny GT 1) ) THEN geometry='yz-plane' ;added + IF ( (nz EQ 1) AND (nx GT 1) AND (ny EQ 1) ) THEN geometry='x-line' ;adjusted + IF ( (nz EQ 1) AND (nx EQ 1) AND (ny GT 1) ) THEN geometry='y-line' ;added + IF ( (nz GT 1) AND (nx EQ 1) AND (ny EQ 1) ) THEN geometry='z-line' ;adjusted + IF ( (nz EQ 1) AND (nx EQ 1) AND (ny EQ 1) ) THEN geometry='point' ;adjusted + + IF n_elements(xyz_motion_xlist) MOD nxnynz NE 0 THEN BEGIN + out_message= "!!! Datarun is incomplete." + geometry='incomplete' + ENDIF + + print,'... and the XYZ geometry is: '+ '"'+geometry+'"' + + CASE geometry OF + 'xyz-volume': BEGIN + temp= reform(xyz_motion_xlist,nwrites,nx,ny,nz) + xar = reform(temp[0,*,*,*]) + x = reform(xar,nxnynz) + temp= reform(xyz_motion_ylist,nwrites,nx,ny,nz) + yar = reform(temp[0,*,*,*]) + y = reform(yar,nxnynz) + temp= reform(xyz_motion_zlist,nwrites,nx,ny,nz) + zar = reform(temp[0,*,*,*]) + z = reform(zar,nxnynz) + temp= reform(xyz_motion_rlist,nwrites,nx,ny,nz) + rar = reform(temp[0,*,*,*]) + r = reform(rar,nxnynz) + temp= reform(xyz_motion_thetalist,nwrites,nx,ny,nz) + thetaar = reform(temp[0,*,*,*]) + theta = reform(thetaar,nxnynz) + temp= reform(xyz_motion_philist,nwrites,nx,ny,nz) + phiar=reform(temp[0,*,*,*]) + phi =reform(phiar,nxnynz) + xvec = reform(xar[*,1,1]) + yvec = reform(yar[1,*,1]) + zvec = reform(zar[1,1,*]) + rvec = [rar[0]] + + xyz = fltarr(3,nx,ny,nz) + xyz[0,*,*,*] = xar[*,*,*] + xyz[1,*,*,*] = yar[*,*,*] + xyz[2,*,*,*] = zar[*,*,*] + + xyzr = fltarr(4,nx,ny,nz,1) + xyzr[0,*,*,*,0] = xar[*,*,*] + xyzr[1,*,*,*,0] = yar[*,*,*] + xyzr[2,*,*,*,0] = zar[*,*,*] + xyzr[3,*,*,*,0] = rar[0] + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,'nwrites',nwrites,$ + 'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_y0,'z0',ml_z0, 'zport', zport, 'fanXYZ', fanXYZ, 'minZ', minZ,'maxZ',maxZ,$ + 'minY',minY,'maxY',maxY,'xlist',xyz_motion_xlist,'ylist',xyz_motion_ylist,'zlist',xyz_motion_zlist,'rlist',xyz_motion_rlist,$ + 'thetalist',xyz_motion_thetalist,'philist',xyz_motion_philist,$ + 'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,$ + 'xar',xar,'yar',yar,'zar',zar,'rar',rar,'thetaar',thetaar,'phiar',phiar,$ + 'xvec',xvec,'yvec',yvec,'zvec',zvec,'rvec',rvec,$ + 'xyz',xyz,'xyzr',xyzr,'r_unique',r_unique,'p_unique',p_unique) + END + + 'xy-plane': BEGIN + temp= reform(xyz_motion_xlist,nwrites,nx,ny) + xar = reform(temp[0,*,*]) + x = reform(xar,nxnynz) + temp= reform(xyz_motion_ylist,nwrites,nx,ny) + yar = reform(temp[0,*,*]) + y = reform(yar,nxnynz) + temp= reform(xyz_motion_zlist,nwrites,nx,ny) + zar = reform(temp[0,*,*]) + z = reform(zar,nxnynz) + temp= reform(xyz_motion_rlist,nwrites,nx,ny) + rar = reform(temp[0,*,*]) + r = reform(rar,nxnynz) + temp= reform(xyz_motion_thetalist,nwrites,nx,ny) + thetaar = reform(temp[0,*,*]) + theta = reform(thetaar,nxnynz) + temp= reform(xyz_motion_philist,nwrites,nx,ny) + phiar=reform(temp[0,*,*]) + phi =reform(phiar,nxnynz) + xvec = reform(xar[*,0]) + yvec = reform(yar[0,*]) + rvec = [rar[0]] + + xy = fltarr(2,nx,ny) + xy[0,*,*] = xar[*,*] + xy[1,*,*] = yar[*,*] + + xyr = fltarr(3,nx,ny,1) + xyr[0,*,*,0] = xar[*,*] + xyr[1,*,*,0] = yar[*,*] + xyr[2,*,*,0] = rar[0] + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,'nwrites',nwrites,$ + 'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_y0,'z0',ml_z0, 'zport', zport, 'fanXYZ', fanXYZ, 'minZ', minZ,'maxZ',maxZ,$ + 'minY',minY,'maxY',maxY,'xlist',xyz_motion_xlist,'ylist',xyz_motion_ylist,'zlist',xyz_motion_zlist,'rlist',xyz_motion_rlist,$ + 'thetalist',xyz_motion_thetalist,'philist',xyz_motion_philist,$ + 'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,$ + 'xar',xar,'yar',yar,'zar',zar,'rar',rar,'thetaar',thetaar,'phiar',phiar,$ + 'xvec',xvec,'yvec',yvec,'rvec',rvec,$ + 'xy',xy,'xyr',xyr,'r_unique',r_unique,'p_unique',p_unique) + END + + 'xz-plane': BEGIN + temp= reform(xyz_motion_xlist,nwrites,nx,nz) + xar = reform(temp[0,*,*]) + x = reform(xar,nxnynz) + temp= reform(xyz_motion_ylist,nwrites,nx,nz) + yar = reform(temp[0,*,*]) + y = reform(yar,nxnynz) + temp= reform(xyz_motion_zlist,nwrites,nx,nz) + zar = reform(temp[0,*,*]) + z = reform(zar,nxnynz) + temp= reform(xyz_motion_rlist,nwrites,nx,nz) + rar = reform(temp[0,*,*]) + r = reform(rar,nxnynz) + temp= reform(xyz_motion_thetalist,nwrites,nx,nz) + thetaar = reform(temp[0,*,*]) + theta = reform(thetaar,nxnynz) + temp= reform(xyz_motion_philist,nwrites,nx,nz) + phiar=reform(temp[0,*,*]) + phi =reform(phiar,nxnynz) + xvec = reform(xar[*,0]) + zvec = reform(zar[0,*]) + rvec = [rar[0]] + + xz = fltarr(2,nx,nz) + xz[0,*,*] = xar[*,*] + xz[1,*,*] = zar[*,*] + + xzr = fltarr(3,nx,nz,1) + xzr[0,*,*,0] = xar[*,*] + xzr[1,*,*,0] = zar[*,*] + xzr[2,*,*,0] = rar[0] + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,'nwrites',nwrites,$ + 'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_y0,'z0',ml_z0, 'zport', zport, 'fanXYZ', fanXYZ, 'minZ', minZ,'maxZ',maxZ,$ + 'minY',minY,'maxY',maxY,'xlist',xyz_motion_xlist,'ylist',xyz_motion_ylist,'zlist',xyz_motion_zlist,'rlist',xyz_motion_rlist,$ + 'thetalist',xyz_motion_thetalist,'philist',xyz_motion_philist,$ + 'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,$ + 'xar',xar,'yar',yar,'zar',zar,'rar',rar,'thetaar',thetaar,'phiar',phiar,$ + 'xvec',xvec,'zvec',zvec,'rvec',rvec,$ + 'xz',xz,'xzr',xzr,'r_unique',r_unique,'p_unique',p_unique) + END + + 'yz-plane': BEGIN + temp= reform(xyz_motion_xlist,nwrites,ny,nz) + xar = reform(temp[0,*,*]) + x = reform(xar,nxnynz) + temp= reform(xyz_motion_ylist,nwrites,ny,nz) + yar = reform(temp[0,*,*]) + y = reform(yar,nxnynz) + temp= reform(xyz_motion_zlist,nwrites,ny,nz) + zar = reform(temp[0,*,*]) + z = reform(zar,nxnynz) + temp= reform(xyz_motion_rlist,nwrites,ny,nz) + rar = reform(temp[0,*,*]) + r = reform(rar,nxnynz) + temp= reform(xyz_motion_thetalist,nwrites,ny,nz) + thetaar = reform(temp[0,*,*]) + theta = reform(thetaar,nxnynz) + temp= reform(xyz_motion_philist,nwrites,ny,nz) + phiar=reform(temp[0,*,*]) + phi =reform(phiar,nxnynz) + yvec = reform(yar[*,0]) + zvec = reform(zar[0,*]) + rvec = [rar[0]] + + yz = fltarr(2,ny,nz) + yz[0,*,*] = yar[*,*] + yz[1,*,*] = zar[*,*] + + yzr = fltarr(3,ny,nz,1) + yzr[0,*,*,0] = yar[*,*] + yzr[1,*,*,0] = zar[*,*] + yzr[2,*,*,0] = rar[0] + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,'nwrites',nwrites,$ + 'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_y0,'z0',ml_z0, 'zport', zport, 'fanXYZ', fanXYZ, 'minZ', minZ,'maxZ',maxZ,$ + 'minY',minY,'maxY',maxY,'xlist',xyz_motion_xlist,'ylist',xyz_motion_ylist,'zlist',xyz_motion_zlist,'rlist',xyz_motion_rlist,$ + 'thetalist',xyz_motion_thetalist,'philist',xyz_motion_philist,$ + 'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,$ + 'xar',xar,'yar',yar,'zar',zar,'rar',rar,'thetaar',thetaar,'phiar',phiar,$ + 'yvec',yvec,'zvec',zvec,'rvec',rvec,$ + 'yz',yz,'yzr',yzr,'r_unique',r_unique,'p_unique',p_unique) + END + + + 'x-line': BEGIN + xvec=fltarr(nx) & zvec=fltarr(nz) & rvec=fltarr(nr) + thetavec = fltarr(nx) + xval=float(0.) & zval=float(0.) & rval=float(0.) + xz = fltarr(2,nx,nz) + xzr = fltarr(3,nx,nz,nr) + xar = fltarr(nx,nz) & zar=fltarr(nx,nz) & rar=fltarr(nx,nz) + + temp = reform(xyz_motion_xlist,nwrites,nx) + x = reform(temp[0,*]) + xvec = x + + temp = reform(xyz_motion_ylist,nwrites,nx) + y = reform(temp[0,*]) + + + temp = reform(xyz_motion_zlist,nwrites,nx) + z = reform(temp[0,*]) + temp = reform(xyz_motion_rlist,nwrites,nx) + r = reform(temp[0,*]) + temp = reform(xyz_motion_thetalist,nwrites,nx) + theta= reform(temp[0,*]) + temp = reform(xyz_motion_philist,nwrites,nx) + phi = reform(temp[0,*]) + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,'nwrites',nwrites,$ + 'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_y0,'z0',ml_z0,'zport', zport, 'fanXYZ', fanXYZ, 'minZ', minZ,'maxZ',maxZ,$ + 'minY',minY,'maxY',maxY,'xlist',xyz_motion_xlist,'ylist',xyz_motion_ylist,'zlist',xyz_motion_zlist,'rlist',xyz_motion_rlist,$ + 'thetalist',xyz_motion_thetalist,'philist',xyz_motion_philist,$ + 'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,$ + 'xvec',xvec,'r_unique',r_unique,'p_unique',p_unique) + END + + 'y-line': BEGIN + xvec=fltarr(nx) & yvec=fltarr(ny) & zvec=fltarr(nz) & rvec=fltarr(nr) + thetavec = fltarr(nx) + xval=float(0.) & yval=float(0.) & zval=float(0.) & rval=float(0.) + + temp = reform(xyz_motion_xlist,nwrites,ny) + x = reform(temp[0,*]) + + temp = reform(xyz_motion_ylist,nwrites,ny) + y = reform(temp[0,*]) + yvec = y + + temp = reform(xyz_motion_zlist,nwrites,ny) + z = reform(temp[0,*]) + temp = reform(xyz_motion_rlist,nwrites,ny) + r = reform(temp[0,*]) + temp = reform(xyz_motion_thetalist,nwrites,ny) + theta= reform(temp[0,*]) + temp = reform(xyz_motion_philist,nwrites,ny) + phi = reform(temp[0,*]) + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,'nwrites',nwrites,$ + 'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_y0,'z0',ml_z0,'zport', zport, 'fanXYZ', fanXYZ, 'minZ', minZ,'maxZ',maxZ,$ + 'minY',minY,'maxY',maxY,'xlist',xyz_motion_xlist,'ylist',xyz_motion_ylist,'zlist',xyz_motion_zlist,'rlist',xyz_motion_rlist,$ + 'thetalist',xyz_motion_thetalist,'philist',xyz_motion_philist,$ + 'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,$ + 'yvec',yvec,'r_unique',r_unique,'p_unique',p_unique) + END + + + + 'z-line': BEGIN + xvec=fltarr(nx) & zvec=fltarr(nz) & rvec=fltarr(nr) + thetavec = fltarr(nz) + xval=float(0.) & zval=float(0.) & rval=float(0.) + + temp = reform(xyz_motion_zlist,nwrites,nz) + z = reform(temp[0,*]) + zvec = z + + temp = reform(xyz_motion_ylist,nwrites,nz) + y = reform(temp[0,*]) + + temp = reform(xyz_motion_xlist,nwrites,nz) + x = reform(temp[0,*]) + + temp = reform(xyz_motion_rlist,nwrites,nz) + r = reform(temp[0,*]) + temp = reform(xyz_motion_thetalist,nwrites,nz) + theta= reform(temp[0,*]) + temp = reform(xyz_motion_philist,nwrites,nz) + phi = reform(temp[0,*]) + + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,'nwrites',nwrites,$ + 'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_y0,'z0',ml_z0,'zport', zport, 'fanXYZ', fanXYZ, 'minZ', minZ,'maxZ',maxZ,$ + 'minY',minY,'maxY',maxY,'xlist',xyz_motion_xlist,'ylist',xyz_motion_ylist,'zlist',xyz_motion_zlist,'rlist',xyz_motion_rlist,'thetalist',xyz_motion_thetalist,$ + 'philist',xyz_motion_philist,'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,$ + 'zvec',zvec,'r_unique',r_unique,'p_unique',p_unique) + END + + + 'point': BEGIN + x=xyz_motion_xlist[0] + y=xyz_motion_ylist[0] + z=xyz_motion_zlist[0] + r=xyz_motion_rlist[0] + theta=xyz_motion_thetalist[0] + phi=xyz_motion_philist[0] + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,'nwrites',nwrites,$ + 'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_y0,'z0',ml_z0,'zport', zport, 'fanXYZ', fanXYZ, 'minZ', minZ,'maxZ',maxZ,$ + 'minY',minY,'maxY',maxY,'xlist',xyz_motion_xlist,'ylist',xyz_motion_ylist,'zlist',xyz_motion_zlist,'rlist',xyz_motion_rlist,$ + 'thetalist',xyz_motion_thetalist,'philist',xyz_motion_philist,$ + 'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,'r_unique',r_unique,'p_unique',p_unique) + END + + 'incomplete': BEGIN + print, '!!! The data could not be completely segmented. The datarun may be incomplete.' + print, '!!! Resegmenting the remaining data as individual shots' + ;;; if the data run stops halfway its not possible to know both the number of + ;;; shots/pos or the number of z-pos from the data itself + nx=1 & ny=1 & nz=1 & nwrites=n_elements(xyz_motion_xlist) + x=xyz_motion_xlist[0] + y=xyz_motion_ylist[0] + z=xyz_motion_zlist[0] + r=xyz_motion_rlist[0] + theta=xyz_motion_thetalist[0] + phi=xyz_motion_philist[0] + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,$ + 'nwrites',nwrites,'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_z0,'z0',ml_z0,$ + 'zport', zport, 'fanXYZ', fanXYZ, 'minZ', minZ,'maxZ',maxZ,'minY',minY,'maxY',maxY,$ + 'xlist',xyz_motion_xlist,'ylist',xyz_motion_ylist,'zlist',xyz_motion_zlist,'rlist',xyz_motion_rlist,$ + 'thetalist',xyz_motion_thetalist,'philist',xyz_motion_philist,$ + 'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,'r_unique',r_unique,'p_unique',p_unique) + END + + + ELSE: PRINT,'Unknown geometry' + ENDCASE + + OBJ_DESTROY, motion_list_group + + no_motion_lists: + IF quiet EQ 0 THEN BEGIN + print,'Nx = ', strtrim(nx,1) + print,'Ny = ', strtrim(ny,1) + print,'Nz = ', strtrim(nz,1) + print,'--------------------------------------------------' + ENDIF + OBJ_DESTROY, motion_group +ENDIF ELSE BEGIN ;end there was a NI_XYZ group + print,'No motion list for this file' + print,'Asigning "point" geometry' + print,'Warning: unable to determine number of writes without a motion list.' + print,'Setting nwrites=1' + nwrites=ulong(1) + motion_list='NONE' + geometry='point' + x=float(0.) & ml_dx = float(0.) + y=float(0.) & ml_dy = float(0.) + z=float(0.) & ml_dz = float(0.) + r=float(0.) + ml_x0 = float(0.) & ml_y0 = float(0.) & ml_z0 = float(0.) + theta=float(0.) + phi=float(0.) + nx = ulong(1) & ny = ulong(1) & nz = ulong(1) & nr = ulong(1) + + mlist = CREATE_STRUCT('motionlist',motion_list,'geom',geometry,'nx',nx,'ny',ny,'nz',nz,'nr',nr,'nwrites',nwrites,$ + 'dx',ml_dx,'dy',ml_dy,'dz',ml_dz,'x0',ml_x0,'y0',ml_y0,'z0',ml_z0,$ + 'x',x,'y',y,'z',z,'r',r,'theta',theta,'phi',phi,'r_unique',r_unique,'p_unique',p_unique) + ENDELSE + +OBJ_DESTROY, HDF5_file + +out_message='NI XYZ done.' +CLEANUP: + +print, out_message +RETURN, mlist +END diff --git a/HDF5/lapd_sis3302_configuration.pro b/HDF5/lapd_sis3302_configuration.pro index a77324c..9af2c4e 100755 --- a/HDF5/lapd_sis3302_configuration.pro +++ b/HDF5/lapd_sis3302_configuration.pro @@ -1,4 +1,4 @@ -FUNCTION lapd_sis3302_configuration,input_file,requested_config_name +FUNCTION lapd_sis3302_configuration, input_file, requested_config_name, quiet=quiet COMPILE_OPT IDL2 s='lapd_sis3302_configuration: ' ;Import Struck Innovative Systems SIS3302 (100MHZ 16bit) class digitizer @@ -16,10 +16,13 @@ s='lapd_sis3302_configuration: ' ; ; ;Modification history: +;Oct 17, 2018 => Added 'quiet' option to suppress non-critical print outputs. ; ; -PRINT,'-----------------------------------------------------------------------' -PRINT,'SIS CRATE, Digitizer type 3302 : Reading configuration for digitizer(s)' +IF quiet EQ 0 THEN BEGIN + PRINT,'-----------------------------------------------------------------------' + PRINT,'SIS CRATE, Digitizer type 3302 : Reading configuration for digitizer(s)' +ENDIF !Quiet=1 sis_structure = {dt:float(0.)} @@ -43,7 +46,6 @@ sis_group_test = WHERE(rac_subgroup_names EQ 'SIS crate') IF (sis_group_test[0] EQ -1) THEN BEGIN print,'No SIS crate module associated with this hdf5 file' goto,cleanup - ENDIF @@ -62,25 +64,31 @@ CASE N_PARAMS() OF ;No configuration name supplied 1: BEGIN - PRINT,'***********************' - PRINT,'No SIS Crate configuration name supplied. Attempting to pick one out.' - IF (N_ELEMENTS(sis_config_group_names) GT 1) THEN BEGIN - PRINT,'SIS Crate 3302: Available configurations:' - PRINT,sis_config_group_names - PRINT + IF quiet EQ 0 THEN BEGIN PRINT,'***********************' - PRINT,'SIS Crate 3302: WARNING: Multiple configurations detected.' - PRINT,'SIS Crate 3302: Using the configuration group name that matches the first dataset name.' + PRINT,'No SIS Crate configuration name supplied. Attempting to pick one out.' + ENDIF + IF (N_ELEMENTS(sis_config_group_names) GT 1) THEN BEGIN + IF quiet EQ 0 THEN BEGIN + PRINT,'SIS Crate 3302: Available configurations:' + PRINT,sis_config_group_names + PRINT + PRINT,'***********************' + PRINT,'SIS Crate 3302: WARNING: Multiple configurations detected.' + PRINT,'SIS Crate 3302: Using the configuration group name that matches the first dataset name.' + ENDIF first_sis_dataset_name=reform(sis_dataset_names[0]) selected_config_group_name = strmid(first_sis_dataset_name,0,stregex(first_sis_dataset_name,'\[')-1) - PRINT - - PRINT,'SIS Crate 3302: This configuration group name is "'+selected_config_group_name+'".' - print,'***********************' + IF quiet EQ 0 THEN BEGIN + PRINT + PRINT,'SIS Crate 3302: This configuration group name is "'+selected_config_group_name+'".' + print,'***********************' + ENDIF ENDIF ELSE BEGIN;Done with more than one sis group case - print,'Only one SIS Crate configuration found: "'+sis_config_group_names[0]+'." Using this one.' + IF quiet EQ 0 THEN print,'Only one SIS Crate configuration found: "'+sis_config_group_names[0]+ $ + '." Using this one.' selected_config_group_name = reform(sis_config_group_names[0]) ENDELSE @@ -88,24 +96,26 @@ CASE N_PARAMS() OF ;configuration name was supplied 2: BEGIN - PRINT,'---' - PRINT,'Requested configuration: '+requested_config_name + IF quiet EQ 0 THEN BEGIN + PRINT,'---' + PRINT,'Requested configuration: '+requested_config_name + ENDIF ii = WHERE(sis_config_group_names EQ requested_config_name) IF (ii[0] EQ -1) THEN BEGIN - MESSAGE,'Requested SIS Crate configuration name ('+requested_config_name+') does not mactch any available configuration.' + MESSAGE,'Requested SIS Crate configuration name ('+requested_config_name+') does not match'+$ + ' any available configuration.' PRINT,'Valid configuration names:' PRINT,sis_config_group_names STOP ENDIF ;requested name found in SIS group. Use it. selected_config_group_name = requested_config_name - END ;Two-argument case ELSE: MESSAGE,'Wrong number of arguments.' ENDCASE -PRINT,'---' +IF quiet EQ 0 THEN PRINT,'---' ; Open the config group that was selected @@ -205,19 +215,19 @@ clock_odd_outputs = '' clock_mode_code = sis3820_config_group->Read_attribute('Clock mode') clock_mode=clock_mode_strings[clock_mode_code] if (clock_mode_code ne 1) then begin - print,s+'Error.' - print,'Only "Straight clock" mode is handled for SIS3820 board' - print,'Current SIS3820 clock mode ='+clock_mode - STOP + print,s+'Error.' + print,'Only "Straight clock" mode is handled for SIS3820 board' + print,'Current SIS3820 clock mode ='+clock_mode + STOP endif clock_source_code = sis3820_config_group->Read_attribute('Clock source') clock_source=clock_source_strings[clock_source_code] if (clock_source_code ne 1) then begin - print,s+'Error.' - print,'Only "2nd Internal 100MHz (U580)" source is handled for SIS3820 board' - print,'Current SIS3820 clock source ='+clock_source - STOP + print,s+'Error.' + print,'Only "2nd Internal 100MHz (U580)" source is handled for SIS3820 board' + print,'Current SIS3820 clock source ='+clock_source + STOP endif @@ -243,7 +253,7 @@ sis_all_slot_numbers = sis_config_group->Read_attribute('SIS crate slot numbers' sis3302_slot_numbers = sis_all_slot_numbers[sis3302_board_indices] sis3302_board_numbers = (sis3302_slot_numbers-5)/2 +1 -print,'SIS3302 boards used:',sis3302_board_numbers +IF quiet EQ 0 THEN print,'SIS3302 boards used:', sis3302_board_numbers n_active_boards = n_elements(sis3302_board_numbers) @@ -286,7 +296,8 @@ for i=0,n_active_boards-1 do begin hardware_average_code = board_config_group->Read_attribute('Sample averaging (hardware)') sample_averaging[iboard,*] = (2L^hardware_average_code) dt[iboard,*] = global_clocktick * float(sample_averaging[iboard,*]) - print,strcompress('SIS3302 : Board '+string(iboard+1)+': Effective clock rate= '+string(1./dt[iboard,0]/1e6)+' MHz') + IF quiet EQ 0 THEN print, strcompress('SIS3302 : Board '+string(iboard+1)+ $ + ': Effective clock rate= '+string(1./dt[iboard,0]/1e6)+' MHz') ;Samples digitized samples[iboard,*] = board_config_group->Read_attribute('Samples') @@ -410,13 +421,12 @@ sis_structure = CREATE_STRUCT('dt',dt,$ 'lc_shots_averaged',lc_shots_averaged) -print,strcompress('Total channels digitized: '+string(nchannels)) - +IF quiet EQ 0 THEN print, strcompress('Total channels digitized: '+string(nchannels)) Cleanup: OBJ_DESTROY, HDF5_file -RETURN,sis_structure +RETURN, sis_structure -END +END \ No newline at end of file diff --git a/HDF5/lapd_sis3305_configuration.pro b/HDF5/lapd_sis3305_configuration.pro index 59ef350..d39306b 100755 --- a/HDF5/lapd_sis3305_configuration.pro +++ b/HDF5/lapd_sis3305_configuration.pro @@ -1,4 +1,4 @@ -FUNCTION lapd_sis3305_configuration,input_file,requested_config_name +FUNCTION lapd_sis3305_configuration, input_file, requested_config_name, quiet=quiet COMPILE_OPT IDL2 s='lapd_sis3305_configuration: ' ;Import Struck Innovative Systems SIS3305 (1.25+GHZ 10bit) class digitizer @@ -19,6 +19,7 @@ s='lapd_sis3305_configuration: ' ; ; ;Modification history: +;Oct 17, 2018 => Added 'quiet' option to suppress non-critical print outputs. ; ; !Quiet=1 @@ -26,8 +27,10 @@ sis_structure = {dt:float(0.)} ; Open HDF5 file. IF (input_file EQ '') THEN input_file = dialog_pickfile(path='./',title='Please choose an HDF5 file') -PRINT,'-----------------------------------------------------------------------' -PRINT,'SIS CRATE, Digitizer type 3305 : Reading configuration for digitizer(s)' +IF quiet EQ 0 THEN BEGIN + PRINT, '-----------------------------------------------------------------------' + PRINT, 'SIS CRATE, Digitizer type 3305 : Reading configuration for digitizer(s)' +ENDIF ; Create the object. HDF5_file = OBJ_NEW('HDF5_file') @@ -305,7 +308,8 @@ for i=0,n_active_boards-1 do begin bw_mode = board_config_group->Read_attribute('Bandwidth') bandwidth[iboard,*] = bw_index_to_bw[bw_mode] - print,strcompress('SIS3305 : Board '+string(iboard+1)+': Effective clock rate= '+string(1./dt[iboard,0]/1e9)+' GHz') + IF quiet EQ 0 THEN print, strcompress('SIS3305 : Board '+string(iboard+1)+ $ + ': Effective clock rate= '+string(1./dt[iboard,0]/1e9)+' GHz') ;Samples digitized samples[iboard,*] = board_config_group->Read_attribute('Samples') @@ -431,13 +435,13 @@ sis_structure = CREATE_STRUCT('dt',dt,$ 'lc_shots_averaged',lc_shots_averaged) -print,strcompress('Total channels digitized: '+string(nchannels)) +IF quiet EQ 0 THEN print, strcompress('Total channels digitized: '+string(nchannels)) Cleanup: OBJ_DESTROY, HDF5_file -RETURN,sis_structure +RETURN, sis_structure -END +END \ No newline at end of file diff --git a/HDF5/read_lapd_data_newsis_ver4.pro b/HDF5/read_lapd_data_newsis_ver4.pro new file mode 100644 index 0000000..f8a2f53 --- /dev/null +++ b/HDF5/read_lapd_data_newsis_ver4.pro @@ -0,0 +1,475 @@ +;================== +;ABOUT THIS ROUTINE: +;================== +;This IDL routine is for reading the lapd hdf5 data files recorded using new SIS3302/3305 and old +;SIS3301 digitizers. Make sure that the IDL PATH includes the folder +; "/usr/local/itt/local_lib/bapsf_hdf5:" +;and routine "check_devices.pro (written by Bart)" is present in the library path. +; +;This routine assumes that the data was recorded in one of the following four configurations +;using only one xy motion plane. This routine does not work if multiple motion lists are used +;or if any other digitizer (e.g. fast TVS or DSOs) is used. +; +;daqconfig 0: standard lapd data run, data recorded in the following order, +; data 2D (time, channel) from daq -> nshots -> xmotion -> ymotion +; +;daqconfig 1: standard lapd data run with an extra variable scan after performing the xy motion, +; data recorded in following sequence; data (time,channel) from daq -> nshots -> +; xmotion -> ymotion -> extra variable steps (e.g. Bfield steps with pause) +; +;daqconfig 2: standard lapd data run with an extra variable scan before performing the xy motion, +; data recorded in following sequence; data (time,channel) from daq -> nshots -> +; extra variable steps (e.g. Bfield steps with pause) -> xmotion -> ymotion +; +;daqconfig 3: no motion list with extra variable scan, set nstep=1 if no variable scan. +; data recorded in following sequence; +; data 2D (time,shot,chan,step) from daq -> nshots on all channels -> +; extra variable steps +; nstep and nshots have to provided at the input while using this config. +; +;daqconfig 4: standard smpd data run, data recorded in the following order, +; data 3D (time, channel) from daq -> nshots -> xmotion -> ymotion -> zmotion + +;=============== +;INPUT VARIABLES +;=============== +;readfname :name of the raw hdf5 file with complete path, string type +;nstep :integer, must specify nstep for daqconfig 1 & 2 & 3. Nstep is the number of +; steps in the extra variable specified above. Optional for daqconfig 0 +; If not set, default nstep = 1 is used. +;daqconfig (optional): 0,1,2 or 3; see description above, default is 0 +;trange (optional): a two element long integer array containing range of time indices to +; read e.g. [1,1000] will read t(1:1000); default read all t +;xrange (optional): a two element integer array containing range of x indices to read e.g. +; [1,3] will read x(1:3); default read all x +;yrange (optional): a two element integer array containing range of y indices to read e.g. +; [1,3] will read y(1:3); default read all y +;zrange (optional): a two element integer array containing range of z indeces to read e.g. +; [1,3] will read z(1:3); default read all z +;shotrange (optional): a two element integer array containing range of shot indices to read e.g. +; [1,3] will read shot(1:3); default read all shots +;readchan (optional): an integer array containing channels to be read e.g. [0,3,5]; default read +; all channels. Start counting channel '0' from the first channel on the first board +; to the last channel on the last board that were used in the data run. +;tchannum (optional): channel number to read the time series info (default is channel 0). This is +; useful when channels share multiple sampling rates or number of samples. +; In single call this routine returns dataset assuming channels in the dataset share +; the time series "t". One can make multiple calls to this routine if multiple sampling +; rates/numbers are used and use this argument to retrieve the correct "t" array. +;tstart (optional): start trigger in second, default value is 0 sec. +;tstop (optional): stop trigger in second, default value is time-range of acquired data in sec. +;sis (optional): default '1' is sis digitizer 3302 (100 MHz), set to '2' for sis 3305 (5GHz) +; set to '3' for old sis digitizer (sis3301). If more than one digitizers are used, +; call this routine multiple times with appropiate 'sis' settings. +;motiondevice (optional): default 'y'. Set it to 'n' and provide nx, ny, nz, x, y, z, nshots for +; reading data when 2D motion (xy or xz) or 3D was performed using non-compumotor +; motion devices. This is also useful if the run crashed without completing and +; x, y, z array cannot be read properly. +;motionid (optional) Set this keyword to an integer corresponding to the motion list of another +; receptacle. This is usually done when the first motion list corresponds to a +; stationary probe. + +;================ +;OUTPUT VARIABLES +;================ +;dataset = Array(nt,nx,ny,nshots,nchan) for daqconfig 0, +; Array(nt,nx,ny,nshots,nchan,nstep) for daqconfig 1 & 2, +; Array(nt,nshots,nchan,nstep) for daqconfig 3, +; Array(nt,nx,ny,nz,nshots,nchan) for daqconfig 4 +;nt = number of time steps in the returned variable t +;nx = number of x steps in the returned variable x +;ny = number of y steps in the returned variable y +;nz = number of z steps in the returned variable z +;nchan = number of channels in the returned variable dataset +;nshots = number of shot in the returned variable dataset +;x = xarray in cm +;y = yarray in cm +;z = zarray in cm +;t = time array in seconds +;theta = an array containing probe angle in radian (angle probe makes with x-axis in xz plane) +;phi = an array containing probe angle in radian (angle probe makes with x-axis in xy plane) + +;================ +;CHANGE LOG +;================ +;Apr 3, 2013 => Written by Shreekrishna, based on Bart's and Steve Vincena's IDL routines +;Sep 25, 2013 => Added daqconfig 3 to read data when no motion lists are used, header section is +; also modified +;Oct 25, 2013 => Removed bug that occurs in reading x & y info, when nx or ny = 1 +;Oct 25, 2013 => Added optional variable "tchannum" to read data when multiple sampling rate/numbers +; are used +;Jun 24, 2015 => Added option to read data with 2D motion performed without compumotor device +; (see variable compumotor) +;Dec 8, 2015 => Added option to read data with old SIS3301 digitizer and optional input 'tstop' +;---- Edits by swjtang ---- +;May 30, 2017 => Added "motionid" option to switch the motion list to that of another probe +; within the dataset +;Oct 3, 2017 => Added additional condition to read only the zeroth channel when readchan=[0] +; since this makes KEYWORD_SET=0 +;Oct 4, 2017 => Added option to read XZ-planes with NI_XZ config +;Oct 9, 2017 => Added 'incomplete' option to read data as individual shots if the datarun +; is incomplete and cannot be reformed -> superceded by motiondevice +;May 24, 2018 => - Changed tchannum to read the first readchan index if readchan is specified. +; - Bug fix: readchan reads channel 0 if readchan=[0] is specified. +; - Update: readchan no longer reads duplicate channels. +;May 26, 2018 => Update: shotrange checks for the case where only one number is specified. +;May 29, 2018 => Update: Included a check and an error message for the case where the file is not +; found. Previously it was not possible to tell from the no motion list error +; message that the filepath is incorrect or the file does not exist. +;Jul 12, 2018 => Added channel numbers in front of the channel info +;Aug 11, 2018 => Added "motiondevice" option to read hdf5 datafiles generated by an incomplete +; datarun. In this case x, y, z array need to be manually provided. +;Aug 17, 2018 => Added option to read XYZ-volume with NI_XYZ config (by kkrynski) +;Sep 6, 2018 => Added option to suppress print output +;Oct 17, 2018 => Added 'quiet' option to suppress non-critical print outputs. (not done for 3301) + +PRO read_lapd_data_newsis_ver4, readfname, dataset, t, x, y, z, nt, nx, ny, nz, nshots, nchan $ + , theta=theta, phi=phi, sis=sis, trange=trange, xrange=xrange, yrange=yrange, zrange=zrange $ + , daqconfig=daqconfig, shotrange=shotrange, readchan=readchan, nstep=nstep $ + , tstart=tstart, tstop=tstop, tchannum=tchannum, motiondevice=motiondevice $ + , motionid=motionid, quiet=quiet;, incomplete=incomplete + + ; Checks if the hdf5 file exists in the directory + IF FILE_TEST(readfname) EQ 0 THEN BEGIN + print, '!!! File not found. Check filename for typos or if the file exists in the directory.' + goto, exitflag + ENDIF + + IF KEYWORD_SET(readchan) THEN readchan=readchan[UNIQ(readchan)] ;removes duplicate channels + IF NOT KEYWORD_SET(nstep) THEN nstep = 1 + IF NOT KEYWORD_SET(nx) THEN nx = 1 + IF NOT KEYWORD_SET(ny) THEN ny = 1 + IF NOT KEYWORD_SET(nz) THEN nz = 1 + IF NOT KEYWORD_SET(nshots) THEN nshots = 1 + IF NOT KEYWORD_SET(theta) THEN theta = 1 + IF NOT KEYWORD_SET(sis) THEN sis = 1 + IF NOT KEYWORD_SET(tstart) THEN tstart = 0.0 + IF NOT KEYWORD_SET(tstop) THEN tstop = 0.0 + IF NOT KEYWORD_SET(tchannum) THEN BEGIN ;automatically uses the first read channel + IF KEYWORD_SET(readchan) THEN tchannum = readchan[0] ELSE tchannum = 0 + ENDIF + IF NOT KEYWORD_SET(motiondevice) THEN motiondevice = 'y' + IF NOT KEYWORD_SET(motionid) THEN motionid = 0 + IF KEYWORD_SET(quiet) THEN BEGIN + quiet=1 + print, "!!! Some print messages are being suppressed." + ENDIF ELSE BEGIN + quiet=0 + ENDELSE + ;IF NOT KEYWORD_SET(incomplete) THEN incomplete = 0 superceded by motiondevice + +TIC ;timer start + +device_check = check_devices(readfname) ;check which devices are being used + +;;;; READ THE DATA PLANE CONFIGURATION ------------------------------------------------------------ +CASE 1 OF + device_check.active[0]: plane_config='XY' ; check if 6K compumotor was active + device_check.active[6]: plane_config='XZ' ; check if NI_XZ was active + device_check.active[7]: plane_config='XYZ' ; check if NI_XYZ was active + ELSE: IF NOT KEYWORD_SET(compumotor) THEN plane_config='no-motion' $ + ELSE plane_config='no-compumotor' +ENDCASE + +geom = 'NA' +IF motiondevice NE 'y' THEN plane_config='manual' + +CASE 1 OF + (plane_config EQ 'XY') OR (plane_config EQ 'XZ') OR (plane_config EQ 'XYZ'): BEGIN + CASE plane_config OF + 'XY' : BEGIN + mlist = lapd_6k_configuration(readfname, motion=motionid, quiet=quiet) + ny = mlist.ny ; number of points in y + IF ny GT 1 THEN y = mlist.yvec + IF ny EQ 1 THEN y = mlist.ylist[0] + dy = mlist.dy ; step size in y + z = 0 + geom = mlist.geom + END + 'XZ': BEGIN + mlist = lapd_ni_xz_configuration(readfname, motion=motionid,quiet=quiet) + nz = mlist.nz ; number of points in z + IF nz GT 1 THEN z = mlist.zvec + IF nz EQ 1 THEN z = mlist.zlist[0] + dz = mlist.dz ; step size in z + y = 0 + geom = mlist.geom + END + 'XYZ': BEGIN + mlist = lapd_ni_xyz_configuration(readfname, motion=motionid, quiet=quiet) + ny = mlist.ny ;number of points in y + nz = mlist.nz ;number of points in z + IF nz GT 1 THEN z = mlist.zvec + IF nz EQ 1 THEN z = mlist.zlist[0] + IF ny GT 1 THEN y = mlist.yvec + IF ny EQ 1 THEN y = mlist.ylist[0] + dz = mlist.dz ;step size in z + dy = mlist.dy ;step size in y + geom = mlist.geom + daqconfig = 4 + END + ENDCASE + nshots = mlist.nwrites ; number of saved shots per position + nx = mlist.nx ; number of points in x + IF nx GT 1 THEN x = mlist.xvec + IF nx EQ 1 THEN x = mlist.xlist[0] + dx = mlist.dx ; step size in x + theta = mlist.theta ; array with probe angle theta + phi = mlist.phi ; array with probe angle phi + nshots /= nstep + END + (plane_config EQ 'no-motion'): BEGIN + nx=1 & ny=1 & nz=1 & x=0 & y=0 & z=0 & theta=0 & phi=0 + print, '!!! No motion lists detected, setting nshots ='+ strtrim(nshots,1) + $ + ' and nstep =',strtrim(nstep,1) + END + (plane_config EQ 'no-compumotor'): BEGIN + print, '!!! No compumotor device, Using nx, ny, x, y, theta, phi from input parameters,'+ $ + ' nx, ny, nshots = ' + strtrim(Nx,1) + strtrim(Ny,1) + strtrim(nshots,1) + END + (plane_config EQ 'manual'): BEGIN + theta=0 & phi=0 + print, '!!! No motion list used, using input x, y, z, setting nshots=' + strtrim(nshots,1) $ + + 'nstep =' + strtrim(nstep,1) + END + ELSE: BREAK +ENDCASE + +;;;; READ THE SIS CRATE CONFIGURATION ------------------------------------------------------------- +CASE sis OF +1: BEGIN + IF device_check.active[2] THEN BEGIN + sis3302list = lapd_sis3302_configuration(readfname, quiet=quiet) ;Getting SIS 3302 digitizer information + nchan = sis3302list.nchannels + dt = sis3302list.lc_dt[tchannum] + nt = sis3302list.lc_samples[tchannum] + boardlist = sis3302list.lc_board_number + chanlist = sis3302list.lc_channel_number + t = findgen(nt)*dt + tstart + IF quiet EQ 0 THEN BEGIN + IF mean(sis3302list.lc_dt) NE dt THEN $ + PRINT,'SIS 3302, multiple sample rates across boards.' + IF mean(sis3302list.lc_samples) NE nt THEN $ + PRINT,'SIS 3302, multiple number of samples across boards.' + print, '----------- Channel Info ---------------------------' + FOR indx=0,nchan-1 do print, '[',string(indx, format='(I2)'),'] Board: ', $ + strtrim(string(sis3302list.lc_board_number(indx)),2),', Channel ', $ + strtrim(string(sis3302list.lc_channel_number(indx)),2), ': ', $ + sis3302list.lc_datatype(indx) + print, '----------------------------------------------------' + ENDIF + ENDIF ELSE BEGIN + PRINT,'SIS 3302 not detected in the hdf5 file, try sis=2 (SIS 3305) or sis=3 (SIS 3301)?' + GOTO, Cleanup + ENDELSE +END +2: BEGIN + IF device_check.active[3] THEN BEGIN + sis3305list = lapd_sis3305_configuration(readfname, quiet=quiet) ;Getting SIS 3305 digitizer information + nchan = sis3305list.nchannels + dt = sis3305list.lc_dt[tchannum] + nt = sis3305list.lc_samples[tchannum] + boardlist = sis3305list.lc_board_number + chanlist = sis3305list.lc_channel_number + t = findgen(nt)*dt + tstart + IF quiet EQ 0 THEN BEGIN + IF mean(sis3305list.lc_dt) NE dt THEN $ + PRINT,'SIS 3305, multiple sampling rates across boards!' + IF mean(sis3305list.lc_samples) NE nt THEN $ + PRINT,'SIS 3305, multiple number of samples across boards!' + print, '----------- Channel Info ---------------------------' + FOR indx=0,nchan-1 DO print,'[',string(indx, format='(I2)'),'] Board: ', $ + strtrim(string(sis3305list.lc_board_number(indx)),2),', Channel ', $ + strtrim(string(sis3305list.lc_channel_number(indx)),2), ': ', $ + sis3305list.lc_datatype(indx) + print, '----------------------------------------------------' + ENDIF + ENDIF ELSE BEGIN + PRINT, 'SIS 3305 not detected in the hdf5 file, try sis=1 (SIS 3302) or sis=3 (SIS 3301)?' + GOTO, Cleanup + ENDELSE +END +3: BEGIN + IF device_check.active[4] THEN BEGIN + sislist = lapd_sis_configuration(readfname) ;Getting SIS 3301 digitizer information + nchan = sislist.nchan ; number of channels + dt = sislist.dt[0] ; time step in seconds + nt = sislist.nt[0] ; number of time samples + t = findgen(nt)*dt + tstart + IF tstop NE 0 THEN t=(findgen(nt)-nt+1)*dt + tstop + ENDIF ELSE BEGIN + PRINT, 'SIS 3301 not detected in the hdf5 file, try sis=1 (SIS 3302) or sis=2 (SIS 3305)?' + GOTO, Cleanup + ENDELSE +END +ENDCASE + +;;;; SPECIFY DEFAULT VARIABLE VALUES -------------------------------------------------------------- + IF NOT KEYWORD_SET(daqconfig) THEN daqconfig = 0 + IF NOT KEYWORD_SET(trange) THEN trange = [0L,long(nt)-1L] + IF NOT KEYWORD_SET(xrange) THEN xrange = [0,nx-1] + IF NOT KEYWORD_SET(yrange) THEN yrange = [0,ny-1] + IF NOT KEYWORD_SET(zrange) THEN zrange = [0,nz-1] + ;checks if only one shot number is specified and if it is [0] + IF NOT KEYWORD_SET(shotrange) THEN BEGIN + IF (n_elements(shotrange) EQ 1) THEN shotrange=[0,0] ELSE shotrange = [0,nshots-1] + ENDIF ELSE BEGIN + IF (n_elements(shotrange) EQ 1) THEN shotrange=[shotrange[0],shotrange[0]] + ENDELSE + IF NOT KEYWORD_SET(readchan) THEN BEGIN + IF (n_elements(readchan) EQ 1) THEN BEGIN + readchan = [0] ; read the 0th channel if zero is the only channel specified + ENDIF ELSE BEGIN + readchan = indgen(nchan) ; otherwise read all channels by default + ENDELSE + ENDIF + + ;;; If the geometry is incomplete, overwrite any (x/y/z)range values. + IF geom EQ 'incomplete' THEN BEGIN + IF quiet EQ 0 THEN BEGIN + print, '!!! The datarun is incomplete. Individual shots will be processed.' + print, '!!! (nx=1, ny=1, nz=1)' + ENDIF + xrange=[0,0] & yrange=[0,0] & zrange=[0,0] + ENDIF + + print,'Read Channels = ', readchan + print,'Shot range = ', strtrim(shotrange[0],1),' to ', strtrim(shotrange[1],1) + print,'X value range = ', strtrim(xrange[0],1),' to ', strtrim(xrange[1],1) + CASE plane_config OF + 'XZ' : BEGIN + ;;;; XZ WILL USE COORDINATES 'X' & 'Y' (2D CASE). COORDINATES RESTORED AT THE END. + mem_y=y & mem_ny=ny & mem_yrange=yrange ; store in memory + y=z & ny=nz & yrange=zrange ; now all y-variables contain z-values + print, 'Z value range = ', strtrim(zrange[0],1),' to ', strtrim(zrange[1],1) + END + 'XYZ': BEGIN + print, 'Y value range = ', strtrim(yrange[0],1),' to ', strtrim(yrange[1],1) + print, 'Z value range = ', strtrim(zrange[0],1),' to ', strtrim(zrange[1],1) + END + ELSE : print, 'Y value range = ', strtrim(yrange[0],1),' to ', strtrim(yrange[1],1) + ENDCASE + + ntt=nt & nxx=nx & nyy=ny & nzz=nz & nchann=nchan & nshotss=nshots ;store values from hdf data + + t = t[trange[0]:trange[1]] ; reduced range of the t, x, y variables + x = x[xrange[0]:xrange[1]] + y = y[yrange[0]:yrange[1]] + z = z[zrange[0]:zrange[1]] + + nt = n_elements(t) & nx = n_elements(x) & ny = n_elements(y) & nz = n_elements(z) + nshots = shotrange[1]-shotrange[0]+1 + nchan = n_elements(readchan) + + mem_req=long64(nt)*nx*ny*nz*nshots*nchan*nstep*4.0e-9 + print,'Estimated memory to read the data (GB):', mem_req + IF mem_req GT 100 THEN BEGIN + print,'!!! Please reduce the data size to keep the required memory below 100 GB' + GOTO, Cleanup + ENDIF + + CASE daqconfig OF + 0: dataset=fltarr(nt,nx,ny,nshots,nchan) ;<< standard lapd data run + 1: dataset=fltarr(nt,nx,ny,nshots,nchan,nstep) ;<< extra steps + 2: dataset=fltarr(nt,nx,ny,nshots,nchan,nstep) + 3: dataset=fltarr(nt,nshots,nchan,nstep) ;<< no xy motion, no extra steps + 4: dataset=fltarr(nt,nx,ny,nz,nshots,nchan) ;<< standard 3D data run + ENDCASE + print,'Dynamic memory used after data variable creation (GB):', string(memory(/current)*1e-9, $ + format='(f7.3)') + + hdf = obj_new('HDF5_file') + hdf -> Open, readfname + + CASE 1 OF + (sis EQ 1) OR (sis EQ 2): sis_group = hdf->Open_group('/Raw data + config/SIS crate') + (sis EQ 3): sis_group = hdf->Open_group('/Raw data + config/SIS 3301') + ENDCASE + +FOR step = 0, nstep-1 DO BEGIN + FOR iz = zrange[0], zrange[1] DO BEGIN + FOR iy = yrange[0], yrange[1] DO BEGIN + FOR ix = xrange[0], xrange[1] DO BEGIN + FOR ishot = shotrange[0], shotrange[1] DO BEGIN + ; if read everything as single shot then print a progress bar + IF geom EQ 'incomplete' THEN BEGIN + outprint='!!! Processing: shot '+string(ishot-shotrange[0]+1, format='(I6)') $ + +' of '+string(nshots,format='(I6)') + print, string(13b), outprint, format='(A,A,$)' + IF ishot EQ shotrange[1] THEN PRINT, ' ' + ENDIF ELSE BEGIN + IF nstep GT 1 THEN BEGIN + outprint='(Step/Shot/XX/YY/ZZ) = ('+strtrim(step+1,1)+'/' $ + + strtrim(ishot-shotrange[0]+1,1) +'/'+ strtrim(ix-xrange[0]+1,1) + '/' $ + + strtrim(iy-yrange[0]+1,1) + '/'+ strtrim(iz-zrange[0]+1,1) + ') of ('$ + + strtrim(nstep,1)+'/'+ strtrim(nshots,1)+'/'+strtrim(nx,1)+'/' $ + + strtrim(ny,1)+'/' + strtrim(nz,1)+ ')...' + ENDIF ELSE BEGIN + outprint='(Shot/XX/YY/ZZ) = (' $ + + strtrim(ishot-shotrange[0]+1,1) +'/'+ strtrim(ix-xrange[0]+1,1) + '/' $ + + strtrim(iy-yrange[0]+1,1) + '/'+ strtrim(iz-zrange[0]+1,1) + ') of ('$ + + strtrim(nshots,1)+'/'+strtrim(nx,1)+'/' $ + + strtrim(ny,1)+'/' + strtrim(nz,1)+ ')...' + ENDELSE + print, string(13b), outprint, format='(A,A,$)' + ;IF ix EQ 8 AND iy EQ 10 AND ishot EQ 1 THEN goto, skipshot ;;; enable when reading SFR54 + ENDELSE + CASE daqconfig OF + ;data loop >> nshots -> xmotion -> ymotion + 0: index= ishot + nshotss*(ix + nxx*iy) + ;data loop >> nshots -> xmotion -> ymotion -> extra variable steps + 1: index= ishot + nshotss*(ix + nxx*(iy + nyy*step)) + ;data loop >> nshots -> extra variable steps -> xmotion -> ymotion + 2: index= ishot + nshotss*(step + nstep*(ix + nxx*iy)) + ;data loop >> nshots + 3: index= ishot + nshotss*steps + ;data loop >> nshots -> xmotion -> ymotion -> zmotion + 4: index= ishot + nshotss*(ix + nxx*iy + nxx*nyy*iz) + ENDCASE + FOR ichan=0, nchan-1 DO BEGIN + CASE sis OF + 1: dattemp = sis_group->read_sis3302_shot(boardlist(readchan[ichan]), $ + chanlist(readchan[ichan]),index) + 2: dattemp = sis_group->read_sis3305_shot(boardlist(readchan[ichan]), $ + chanlist(readchan[ichan]),index) + 3: dattemp = sis_group->read_sis_shot(readchan[ichan],index) + ENDCASE + CASE daqconfig OF + 0: dataset[*,ix-xrange[0],iy-yrange[0],ishot-shotrange[0],ichan] $ + = dattemp[trange[0]:trange[1]] + 1: dataset[*,ix-xrange[0],iy-yrange[0],ishot-shotrange[0],ichan,step] $ + = dattemp[trange[0]:trange[1]] + 2: dataset[*,ix-xrange[0],iy-yrange[0],ishot-shotrange[0],ichan,step] $ + = dattemp[trange[0]:trange[1]] + 3: dataset[*,ishot-shotrange[0],ichan,step] $ + = dattemp[trange[0]:trange[1]] + 4: dataset[*,ix-xrange[0],iy-yrange[0],iz-zrange[0],ishot-shotrange[0],ichan] $ + = dattemp[trange[0]:trange[1]] + ENDCASE + ENDFOR; loop for channels + skipshot: + ENDFOR; loop for shots + ENDFOR; loop for x + ENDFOR; loop for y + ENDFOR; loop for z +ENDFOR; loop for steps +print, ' ' + +; ;;;; RESTORE VARIABLES IF XZ WAS USED +IF plane_config EQ 'XZ' THEN BEGIN + z=y & nz=ny & zrange=yrange ; pass all z-values to the z-variables + y=mem_y & ny=mem_ny & yrange=mem_yrange ; restore y-values from memory +END + +OBJ_DESTROY, sis_group +OBJ_DESTROY, hdf + +print, 'Completed reading raw data: ',systime(0) +TOC ;timer end + +cleanup: PRINT,' ' + print, 'Read LAPD Data complete' + help, dataset + +exitflag: +END \ No newline at end of file