Changeset 175
- Timestamp:
- May 7, 2010 11:28:17 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
dc2mda/src/pythonlib/dc2mda.py
r174 r175 17 17 import struct 18 18 import sys 19 import mda19 import traceback 20 20 import data_types # EPICS & IDL data types 21 import mda # read/write support for MDA files 21 22 22 23 … … 217 218 elif rank == 1: 218 219 # 1-D array 219 myDict['count'] = count =s1220 myDict['count'] = s1 220 221 myDict['type'] = type = s2 221 222 myDict['nx'] = nx = s3 … … 225 226 myDict['ny'] = ny = s2 226 227 myDict['type'] = type = s3 227 myDict['count'] = count =s4 # total number of values228 myDict['count'] = s4 # total number of values 228 229 else: 229 230 msg = offsetHex + ": " … … 245 246 data = [] 246 247 self.read_LONG(fp) # another string length DWORD 247 for iin range(ny):248 for __i__ in range(ny): 248 249 row = "" 249 for jin range(nx):250 for __j__ in range(nx): 250 251 c = fp.read(1) 251 252 if ord(c) > 0: … … 255 256 else: 256 257 data = [] 257 for iin range(nx):258 for __i__ in range(nx): 258 259 data.append(self.read_BYTE(fp)) 259 260 elif type == 2: # INT 260 261 data = [] 261 262 if rank == 2: 262 for iin range(ny):263 for __i__ in range(ny): 263 264 row = [] 264 for jin range(nx):265 for __j__ in range(nx): 265 266 if isIndexFile: 266 267 row.append(self.read_INT(fp)) … … 269 270 data.append(row) 270 271 else: 271 for iin range(nx):272 for __i__ in range(nx): 272 273 if isIndexFile: 273 274 data.append(self.read_INT(fp)) … … 278 279 data = [] 279 280 if rank == 2: 280 for iin range(ny):281 for __i__ in range(ny): 281 282 row = [] 282 for jin range(nx):283 for __j__ in range(nx): 283 284 row.append(self.read_LONG(fp)) 284 285 data.append(row) 285 286 else: 286 for iin range(nx):287 for __i__ in range(nx): 287 288 data.append(self.read_LONG(fp)) 288 289 elif type == 4: # FLOAT 289 290 data = [] 290 291 if rank == 2: 291 for iin range(ny):292 for __i__ in range(ny): 292 293 row = [] 293 for jin range(nx):294 for __j__ in range(nx): 294 295 row.append(self.read_FLOAT(fp)) 295 296 data.append(row) 296 297 else: 297 for iin range(nx):298 for __i__ in range(nx): 298 299 data.append(self.read_FLOAT(fp)) 299 300 elif type == 5: # DOUBLE 300 301 data = [] 301 302 if rank == 2: 302 for iin range(ny):303 for __i__ in range(ny): 303 304 row = [] 304 for jin range(nx):305 for __j__ in range(nx): 305 306 row.append(self.read_DOUBLE(fp)) 306 307 data.append(row) 307 308 else: 308 for iin range(nx):309 for __i__ in range(nx): 309 310 data.append(self.read_DOUBLE(fp)) 310 311 elif type == 6: # COMPLEX … … 320 321 elif rank == 1: 321 322 data = [] 322 for iin range(nx):323 for __i__ in range(nx): 323 324 data.append(self.read_STRING(fp, 324 325 numChars=s4, strip=True, indexFile=isIndexFile)) … … 527 528 name = records[i * 5 + 0] 528 529 qno = records[i * 5 + 1] 529 keyList = ['x', 'y', 'image']530 for j in range(len(keyList)):531 dict[keyList[j]] = records[i * 5 + 2 + j]['data']532 530 keyList = ['PV inner scan', 'PV outer scan', 'file 1D data', 533 531 'PV 1D scan positioner 1', 'PV 2D scan positioner 1', … … 540 538 dict[keyList[j]] = qno['data'][j] 541 539 #print 'DEBUG:', dict['2D scanno'], dict['1D scanno'] 540 #pprint.pprint(dict) 541 keyList = ['x', 'y', 'image'] 542 for j in range(len(keyList)): 543 dict[keyList[j]] = records[i * 5 + 2 + j]['data'] 542 544 images.append(dict) 543 545 return images … … 587 589 dict['Scan data file name'] = strings[3] 588 590 dict['time'] = strings[4].split(".")[0].strip() 589 dict['userID'] = strings[4].split(".")[1]. strip()591 dict['userID'] = strings[4].split(".")[1].replace("User Name:", "", 1).strip() 590 592 dict['comment'] = strings[5] 591 593 seqno = records[recNum]['data']; recNum += 1 … … 650 652 header['ourKeys'].append('time') 651 653 header['time'] = scan['time'] 652 for entry in scan['env']: 653 header[entry['pv']] = (entry['description'], '', entry['value'], 0, 1) 654 header.update( self.buildEnvMetadata(scan) ) 654 655 # add metadata from the catcher file as "environment" data 655 EPICS_datatype = 0 656 envKeys = ['userID', 'version', 'comment', 'time'] 657 for i in range(len(envKeys)): 658 key = envKeys[i] 659 value = scan[key] 660 pv = self.keyToPv(key) 661 header[pv] = (key, '', value, EPICS_datatype, 1) 656 header.update( 657 self.buildPvMetadata( 658 'DBR_STRING', 659 ['userID', 'version', 'comment', 'time'], 660 scan) 661 ) 662 662 # strings 663 envKeys = ['Plot title', 'Plot x label', 'Plot y label', 'Scan data file name', 'pv', 'filename'] 664 for i in range(len(envKeys)): 665 key = envKeys[i] 666 value = scan[key] 667 pv = self.keyToPv(key) 668 header[pv] = (key, '', value, EPICS_datatype, 1) 669 header['filename_short'] = ('short file name', '', scan['filename'], EPICS_datatype, 1) 663 header.update( 664 self.buildPvMetadata( 665 'DBR_STRING', 666 ['Plot title', 'Plot x label', 'Plot y label', 667 'Scan data file name', 'pv', 'filename'], 668 scan) 669 ) 670 header['filename_short'] = ( 671 'short file name', '', scan['filename'], 0, 1) 670 672 # floats 671 EPICS_datatype = data_types.EPICS_types_dict_REVERSE['DBR_CTRL_DOUBLE'] 672 envKeys = ['Y positioner value at given 2D scan number'] 673 for i in range(len(envKeys)): 674 key = envKeys[i] 675 value = scan[key] 676 pv = self.keyToPv(key) 677 header[pv] = (key, '', [value], EPICS_datatype, 1) 673 header.update( 674 self.buildPvMetadata( 675 'DBR_CTRL_DOUBLE', 676 ['Y positioner value at given 2D scan number'], 677 scan) 678 ) 678 679 # ints 679 EPICS_datatype = data_types.EPICS_types_dict_REVERSE['DBR_CTRL_LONG'] 680 envKeys = [ 681 '1D scan number, zero based', 682 '1D scan starting reference case number', 683 '2D scanning sequence number, Y loop index number', 684 '2D scan number, zero based', 685 '2D scanning indicator', 686 '2D scan requested number of data points', 687 '2D scan current acquired number' 688 ] 689 for i in range(len(envKeys)): 690 key = envKeys[i] 691 value = scan[key] 692 pv = self.keyToPv(key) 693 header[pv] = (key, '', [value], EPICS_datatype, 1) 680 header.update( 681 self.buildPvMetadata( 682 'DBR_CTRL_LONG', 683 [ 684 '1D scan number, zero based', 685 '1D scan starting reference case number', 686 '2D scanning sequence number, Y loop index number', 687 '2D scan number, zero based', 688 '2D scanning indicator', 689 '2D scan requested number of data points', 690 '2D scan current acquired number' 691 ], 692 scan) 693 ) 694 694 #------------ 1-D scan data_1D 695 695 data_1D = mda.scanDim() … … 751 751 print 752 752 753 def collateFrameSets(self, images): 754 ''' 755 Gather the frame sets from the acquired images 756 @param images: entries from records in data.file.image. 757 Determine how many different 2-D scans (frameSets) we have. 758 That is the number of MDA files we will create. 759 @return: list frameSet dictionaries 753 def collateFrameSets(self, dcFile, scans, index, images): 754 ''' 755 Used by 2D processing to identify sets of images 756 (different detectors with the same 2D scan number) 757 @return: dictionary of image frameSets 758 @note: one MDA file will be written for each frameSet 760 759 ''' 761 760 frameSets = {} 762 for image_index in range(len(images)): 763 image = images[image_index] 764 # index of 1st 1D scan (X data) 765 n1D = image['1D scanno'] - image['ny'] 766 n2D = image['2D scanno'] # one-based 767 if not n2D in frameSets.keys(): 768 frameSets[n2D] = { 769 'first 1D scan num': n1D, 770 '2D scan num': n2D, 771 'detector pv list': [], 772 '1D scan list' : range(n1D, image['1D scanno']), 773 'image frame list': [] 774 } 775 detPv1 = image['PV Detector 1'] 776 frameSets[n2D]['detector pv list'].append(detPv1) 777 frameSets[n2D]['image frame list'].append(image_index) 778 if DC2MDA_DEBUG: pprint.pprint(frameSets) 761 for imageNum in range(len(images)): 762 image = images[imageNum] 763 #len_inner = len(image['image'][0]) 764 len_outer = len(image['image']) 765 if len_outer > 1: 766 scan2DNum = image['2D scanno'] 767 if not scan2DNum in frameSets.keys(): 768 scan1DNum = image['1D scanno'] - image['ny'] 769 if (scan1DNum >= 0) and (scan1DNum < len(scans)): 770 frame = frameSets[scan2DNum] = {} 771 frame['2D scan number'] = scan2DNum 772 frame['x'] = image['x'] 773 frame['y'] = image['y'] 774 frame['imageList'] = [imageNum] 775 frame['image1'] = imageNum 776 frame['scan1'] = scan1DNum 777 else: 778 frame = frameSets[scan2DNum] 779 if (frame['x'] == image['x']) and (frame['y'] == image['y']): 780 frame['imageList'].append(imageNum) 779 781 return frameSets 782 783 def buildEnvMetadata(self, scan): 784 ''' 785 build a dictionary of metadata for 786 the MDA file from the scan environment 787 ''' 788 result = {} 789 for entry in scan['env']: # env variables from first 1-D scan 790 result[entry['pv']] = (entry['description'], '', entry['value'], 0, 1) 791 return result 792 793 def buildPvMetadata(self, EPICS_type_str, keyList, db): 794 ''' 795 build a dictionary of metadata for the MDA file 796 by harvesting specific additional items 797 ''' 798 EPICS_datatype = data_types.EPICS_types_dict_REVERSE[EPICS_type_str] 799 result = {} 800 for i in range(len(keyList)): 801 key = keyList[i] 802 if EPICS_type_str == 'DBR_STRING': 803 value = db[key] 804 else: 805 value = [db[key]] # anything not a string must be in a list 806 pv = self.keyToPv(key) 807 result[pv] = (key, '', value, EPICS_datatype, 1) 808 return result 809 780 810 781 811 def translateMDA_2D(self, dcFile, indexFile, imageFile): … … 796 826 images = self.parseImageRecords(self.readFileRecords(imageFile)) 797 827 798 # Determine how many different 2-D scans (frameSets) we have. 799 # That is the number of MDA files we will create. 800 frameSets = self.collateFrameSets(images) 801 828 # group images by same 2D scan number 829 frameSets = self.collateFrameSets(dcFile, scans, index, images) 830 802 831 for frameNum in frameSets: 803 frame Set= frameSets[frameNum]832 frame = frameSets[frameNum] 804 833 outputMdaFileName = self.FILE_TEMPLATE_2D % (dcFile, frameNum) 805 scan1Num = frameSet['1D scan list'][0] 806 if (scan1Num < 0) or (scan1Num >= len(scans)): 807 fmt = "(%d: Requested data from missing 1D scan #%d)" 808 msg = fmt % (frameNum, scan1Num) 809 print msg, 810 continue 811 scan1 = scans[scan1Num] 812 image1Num = frameSet['image frame list'][0] 813 image1 = images[image1Num] 834 scan1 = scans[frame['scan1']] 835 image1 = images[frame['image1']] 836 scanLen_inner = len(frame['x']) 837 scanLen_outer = len(frame['y']) 814 838 #-------------------------- MDA header ------------------------ 815 839 header = { … … 820 844 header['version'] = MDA_VERSION_FOR_MDAEXPLORER # float 821 845 header['rank'] = 2 822 header['scan_number'] = frameSet['2D scan num'] # one-based 823 scan1_len = image1['nx'] 824 scan2_len = image1['ny'] 825 header['dimensions'] = [scan2_len, scan1_len] 846 header['scan_number'] = frame['2D scan number'] # one-based 847 header['dimensions'] = [scanLen_outer, scanLen_inner] 826 848 header['isRegular'] = 1 # What else could it be but regular? 827 849 header['ourKeys'] = ['sampleEntry', 'filename', 'version', 'scan_number', … … 830 852 header['time'] = scan1['time'] 831 853 #----- environment data 832 for entry in scan1['env']: # env variables from first 1-D scan 833 header[entry['pv']] = (entry['description'], '', entry['value'], 0, 1) 854 header.update( self.buildEnvMetadata(scan1) ) 834 855 # add metadata from the catcher files as "environment" data 835 envKeys = ['userID', 'version', 'comment', 'time'] 836 for i in range(len(envKeys)): 837 key = envKeys[i] 838 value = scan1[key] 839 pv = self.keyToPv(key) 840 header[pv] = (key, '', value, 0, 1) 841 envKeys = ['nx', 'ny'] 842 for i in range(len(envKeys)): 843 key = envKeys[i] 844 value = [image1[key]] # integers must be in lists 845 pv = self.keyToPv(key) 846 header[pv] = (key, '', value, data_types.EPICS_types_dict_REVERSE['DBR_CTRL_LONG'], 1) 847 del pv, key, value, i, envKeys 848 header['filename_short'] = ('short file name', '', scan1['Scan data file name'], 0, 1) 849 header['filename_long'] = ('long file name', '', index['filename'], 0, 1) 856 header.update( 857 self.buildPvMetadata( 858 'DBR_STRING', 859 ['userID', 'version', 'comment', 'time'], 860 scan1) 861 ) 862 header.update( 863 self.buildPvMetadata('DBR_CTRL_LONG', ['nx', 'ny'], image1) 864 ) 865 866 items = [ 867 ['filename_short', 'short file name', 'Scan data file name'], 868 ['filename_long', 'long file name','filename'], 869 ['filename_1D_data', '1-D data file name', 'file 1D data'], 870 ['PV_outer_scan', 'outer scan record PV', 'PV outer scan'], 871 ['PV_inner_scan', 'inner scan record PV', 'PV inner scan'], 872 ['PV_detector_1', 'detector 1 PV', 'PV Detector 1'], 873 ['PV_pos_1_inner', 'positioner 1 PV, inner scan', 'PV 2D scan positioner 1'], 874 ['PV_pos_1_outer', 'positioner 1 PV, outer scan','PV 1D scan positioner 1'] 875 ] 876 for row in items: 877 key, desc, value = row 878 header[key] = (desc, '', value, 0, 1) 879 850 880 header['filename_current'] = ('current file name', '', dcFile, 0, 1) 851 header['filename_1D_data'] = ('1-D data file name', '', image1['file 1D data'], 0, 1)852 881 header['filename_2D_data'] = ('2-D data file name', '', imageFile, 0, 1) 853 header['PV_outer_scan'] = ('outer scan record PV', '', image1['PV outer scan'], 0, 1)854 header['PV_inner_scan'] = ('inner scan record PV', '', image1['PV inner scan'], 0, 1)855 header['PV_detector_1'] = ('detector 1 PV', '', image1['PV Detector 1'], 0, 1)856 header['PV_pos_1_inner'] = ('positioner 1 PV, inner scan', '', image1['PV 2D scan positioner 1'], 0, 1)857 header['PV_pos_1_outer'] = ('positioner 1 PV, outer scan', '', image1['PV 1D scan positioner 1'], 0, 1)858 882 #-------------------------- MDA outer scan ------------------------ 859 883 outer = mda.scanDim() … … 861 885 outer.dim = 1 862 886 outer.name = image1['PV outer scan'] 863 outer.npts = scan2_len # requested 864 outer.curr_pt = len(image1['y']) # actual number of points 865 if outer.curr_pt > outer.npts: 866 outer.npts = outer.curr_pt 887 outer.npts = len(image1['image']) # physical size 888 outer.curr_pt = len(image1['y']) # actual number of points (same) 867 889 outer.time = scan1['time'] 868 890 # ......... … … 875 897 pos.unit = '' 876 898 pos.step_mode = "LINEAR" 877 pos.data = image1['y'] 899 pos.data = frame['y'] 900 for __i__ in xrange(len(frame['y']), outer.npts): 901 pos.data.append(0.0) 878 902 outer.p.append(pos) 879 903 # .......... 880 outer.d = [] 904 outer.d = [] # no detector data in outer scan 881 905 # .......... 882 906 outer.np = len(outer.p) … … 887 911 inner.dim = 2 888 912 inner.name = image1['PV inner scan'] 889 inner.npts = scan1_len # requested 913 inner.npts = len(image1['image'][0]) # physical size # requested 914 inner.curr_pt = len(frame['x']) # actual number of points 890 915 inner.time = scan1['time'] 891 inner.curr_pt = len(image1['x']) # actual number of points892 interruptedScanLength = None # for interrupted scans893 if inner.curr_pt > inner.npts:894 inner.npts = inner.curr_pt895 916 # .......... 896 for posNum in range(len(scan1['pos'])): 897 if scan1['pos'][posNum]['defined'] == 1: 898 pos = mda.scanPositioner() 899 pos.number = posNum 900 pos.fieldName = mda.posName(posNum) # scan-record field (e.g., 'P1') 901 pos.name = scan1['pos'][posNum]['pv'] 902 pos.desc = scan1['pos'][posNum]['description'] 903 pos.unit = scan1['pos'][posNum]['units'] 904 pos.step_mode = "LINEAR" 905 pos.data = [] 906 # Why not use the image data instead? 907 for scanNum in frameSet['1D scan list']: 908 # what about array length on inner scans? 909 #fmt = "scan1Num: %d" 910 #fmt += " posNum: %d" 911 #fmt += " scan1Num: %d" 912 #fmt += " inner.npts: %d" 913 #fmt += " inner.curr_pt: %d" 914 #fmt += " len(posData): %d" 915 posData = scans[scanNum]['pos'][posNum]['data'] 916 #print "scanNum:", scanNum, " posNum:", posNum, " len(posData):", len(posData) 917 if len(posData) < inner.curr_pt: 918 if (interruptedScanLength == None) or (len(posData) < interruptedScanLength): 919 interruptedScanLength = len(posData) 920 # must pad the data array, use zeroes 921 padLength = inner.curr_pt - len(posData) 922 moreData = [0]*padLength 923 posData.extend(moreData) 924 #print fmt % (scan1Num, posNum, scan1Num, inner.npts, inner.curr_pt, len(posData)) 925 pos.data.append(posData) 926 #print "len(posData):", len(posData), " len(pos.data):", len(pos.data) 927 inner.p.append(pos) 928 del pos 917 # only 1 positioner in inner scan is saved in catcher image file 918 pos = mda.scanPositioner() 919 pos.number = 0 920 pos.fieldName = 'P1' # scan-record field (e.g., 'P1') 921 pos.name = image1['PV 1D scan positioner 1'] 922 pos.desc = pos.name 923 pos.unit = '' 924 pos.step_mode = "LINEAR" 925 pos.data = [] 926 for __i__ in range(outer.npts): # need copies of the same thing 927 pos.data.append(frame['x']) 928 inner.p.append(pos) 929 929 # .......... 930 for detNum in range(len(scan1['det'])): 931 if scan1['det'][detNum]['defined'] == 1: 932 det = mda.scanDetector() 933 det.number = detNum 934 det.fieldName = mda.detName(detNum) # scan-record field (e.g., 'D01') 935 det.name = scan1['det'][detNum]['pv'] 936 det.desc = scan1['det'][detNum]['description'] 937 det.unit = scan1['det'][detNum]['units'] 938 det.data = [] 939 for scanNum in frameSet['1D scan list']: 940 detData = scans[scanNum]['det'][detNum]['data'] 941 if len(detData) < inner.curr_pt: 942 # must pad the data array, use zeroes 943 padLength = inner.curr_pt - len(detData) 944 moreData = [0]*padLength 945 detData.extend(moreData) 946 det.data.append(detData) 947 inner.d.append(det) 930 for imgNum in frame['imageList']: 931 image = images[imgNum] 932 det = mda.scanDetector() 933 det.number = image['2D detector number'] 934 det.fieldName = mda.detName(det.number) # such as 'D01' 935 det.name = scan1['det'][det.number]['pv'] 936 det.desc = scan1['det'][det.number]['description'] 937 det.unit = scan1['det'][det.number]['units'] 938 det.data = image['image'] 939 for __i__ in xrange(len(det.data), outer.npts): 940 det.data.append([0]*inner.npts) 941 inner.d.append(det) 948 942 # .......... 949 943 inner.np = len(inner.p) … … 957 951 print frameNum, 958 952 except: 959 type, value, traceback = sys.exc_info() 960 print "Error with frame %d in call mda.writeMDA()\n%s\n%s\n%s" % (frameNum, type, value, traceback) 953 print traceback.print_exc() 954 #type, value, traceback = sys.exc_info() 955 #fmt = "Error with frame %d in call mda.writeMDA()\n%s\n%s\n%s" 956 #print fmt % (frameNum, type, value, traceback) 961 957 pass 962 958 … … 988 984 989 985 if __name__ == '__main__': 990 print SVN_ID991 986 file = TEST_1D_DC_FILE # for code development 992 987 file = TEST_2D_DC_FILE # for code development 993 988 if len(sys.argv) == 2: 994 file = sys.argv[1] 989 file = sys.argv[1].strip() 995 990 elif not os.path.exists(file): 996 991 print "usage: ", sys.argv[0], " path/to/data_catcher_file"
Note: See TracChangeset
for help on using the changeset viewer.