function convert_princeton_header2, header ;+ ; NAME: ; CONVERT_PRINCETON_HEADER2 ; ; PURPOSE: ; Converts headers of data files written by Princeton Instruments' ; WinSPEC and WinVIEW software into a structure ; ; CATEGORY: ; File input. ; ; CALLING SEQUENCE: ; hstruct = convert_princeton_header2(header) ; ; INPUTS: ; header: ; byte Array[4100]. The first 4100 bytes of a P.I. data file ; ; OUTPUTS: ; hstruct - structure with header information ; ; MODIFICATION HISTORY: ; Modified from convert_princeton_header ; (called by read_princeton, which was written by Mark Rivers) ; Leslie Young (Southwest Research Institute) 08/05/07 ; changed name to convert_princeton_header2 ; - added documentation ; - added interpretation of ROI structures ; - added interpretation of Avalanche Gain info ;- ; NOTE: the following values should not change, otherwise the header will ; be bleeped up. HDRNAMEMAX = 120 ; max char str length for file name USERINFOMAX = 1000 ; user information space. COMMENTMAX = 80 ; User comment string max length (5 comments) LABELMAX = 16 ; Label string max length. FILEVERMAX = 16 ; File version string max length. DATEMAX = 10 ; string length of file creation date string as ddmmmyyyy\0 ROIMAX = 10 ; Max size of roi array of structures. TIMEMAX = 7 ; Max time store as hhmmss\0 str = {princeton_header} str.ControllerVersion = fix(header, 0) ; 0 Hardware Version str.LogicOutput = fix(header, 2) ; 2 Definition of Output BNC str.AmpHiCapLowNoise = fix(header, 4) ; 4 Amp Switching Mode str.xDimDet = fix(header, 6) ; 6 Detector x dimension of chip. str.mode = fix(header, 8) ; 8 timing mode str.exp_sec = float(header, 10) ; 10 alternitive exposure, in sec. str.VChipXdim = fix(header, 14) ; 14 Virtual Chip X dim str.VChipYdim = fix(header, 16) ; 16 Virtual Chip Y dim str.yDimDet = fix(header, 18) ; 18 y dimension of CCD or detector. temp = byte(header, 20, DATEMAX) ; 20 date str.date = string(temp) ; 20 date str.VirtualChipFlag = fix(header, 30) ; 30 On/Off str.Spare_1 = byte(header, 32, 2) ; 32 str.noscan = fix(header, 34) ; 34 Old number of scans - should always be -1 str.DetTemperature = float(header, 36) ; 36 Detector Temperature Set str.DetType = fix(header, 40) ; 40 CCD/DiodeArray type str.xdim = fix(header, 42) ; 42 actual # of pixels on x axis str.stdiode = fix(header, 44) ; 44 trigger diode str.DelayTime = float(header, 46) ; 46 Used with Async Mode str.ShutterControl = fix(header, 50) ; 50 Normal, Disabled Open, Disabled Closed str.AbsorbLive = fix(header, 52) ; 52 On/Off str.AbsorbMode = fix(header, 54) ; 54 Reference Strip or File str.CanDoVirtualChipFlag = fix(header, 56) ; 56 T/F Cont/Chip able to do Virtual Chip str.ThresholdMinLive = fix(header, 58) ; 58 On/Off str.ThresholdMinVal = float(header, 60) ; 60 Threshold Minimum Value str.ThresholdMaxLive = fix(header, 64) ; 64 On/Off str.ThresholdMaxVal = float(header, 66) ; 66 Threshold Maximum Value str.SpecAutoSpectroMode = fix(header, 70) ; 70 T/F Spectrograph Used str.SpecCenterWlNm = float(header, 72) ; 72 Center Wavelength in Nm str.SpecGlueFlag = fix(header, 76) ; 76 T/F File is Glued str.SpecGlueStartWlNm = float(header, 78) ; 78 Starting Wavelength in Nm str.SpecGlueEndWlNm = float(header, 82) ; 82 Starting Wavelength in Nm str.SpecGlueMinOvrlpNm = float(header, 86) ; 86 Minimum Overlap in Nm str.SpecGlueFinalResNm = float(header, 90) ; 90 Final Resolution in Nm str.PulserType = fix(header, 94) ; 94 0=None, PG200=1, PTG=2, DG535=3 str.CustomChipFlag = fix(header, 96) ; 96 T/F Custom Chip Used str.XPrePixels = fix(header, 98) ; 98 Pre Pixels in X direction str.XPostPixels = fix(header, 100) ; 100 Post Pixels in X direction str.YPrePixels = fix(header, 102) ; 102 Pre Pixels in Y direction str.YPostPixels = fix(header, 104) ; 104 Post Pixels in Y direction str.asynen = fix(header, 106) ; 106 asynchron enable flag 0 = off str.datatype = fix(header, 108) ; 108 experiment datatype ; 0 = FLOATING POINT ; 1 = LONG INTEGER ; 2 = INTEGER ; 3 = UNSIGNED INTEGER str.PulserMode = fix(header, 110) ; 110 Repetitive/Sequential str.PulserOnChipAccums = fix(header, 112) ; 112 Num PTG On-Chip Accums str.PulserRepeatExp = long(header, 114) ; 114 Num Exp Repeats (Pulser SW Accum) str.PulseRepWidth = float(header, 118) ; 118 Width Value for Repetitive pulse (usec) str.PulseRepDelay = float(header, 122) ; 122 Width Value for Repetitive pulse (usec) str.PulseSeqStartWidth = float(header, 126) ; 126 Start Width for Sequential pulse (usec) str.PulseSeqEndWidth = float(header, 130) ; 130 End Width for Sequential pulse (usec) str.PulseSeqStartDelay = float(header, 134) ; 134 Start Delay for Sequential pulse (usec) str.PulseSeqEndDelay = float(header, 138) ; 138 End Delay for Sequential pulse (usec) str.PulseSeqIncMode = fix(header, 142) ; 142 Increments: 1=Fixed, 2=Exponential str.PImaxUsed = fix(header, 144) ; 144 PI-Max type controller flag str.PImaxMode = fix(header, 146) ; 146 PI-Max mode str.PImaxGain = fix(header, 148) ; 148 PI-Max Gain str.BackGrndApplied = fix(header, 150) ; 150 1 if background subtraction done str.PImax2nsBrdUsed = fix(header, 152) ; 152 T/F PI-Max 2ns Board Used str.minblk = fix(header, 154) ; 154 min. # of strips per skips str.numminblk = fix(header, 156) ; 156 # of min-blocks before geo skps str.SpecMirrorLocation = fix(header, 158, 2) ; 158 Spectro Mirror Location, 0=Not Present str.SpecSlitLocation = fix(header, 162, 4) ; 162 Spectro Slit Location, 0=Not Present str.CustomTimingFlag = fix(header, 170) ; 170 T/F Custom Timing Used temp = byte(header, 172, TIMEMAX); 172 Experiment Local Time as hhmmss\0 str.ExperimentTimeLocal = string(temp) ; 172 Experiment Local Time as hhmmss\0 temp = byte(header, 179, TIMEMAX); 179 Experiment UTC Time as hhmmss\0 str.ExperimentTimeUTC = string(temp) ; 179 Experiment UTC Time as hhmmss\0 str.ExposUnits = fix(header, 186) ; 186 User Units for Exposure str.ADCoffset = fix(header, 188) ; 188 ADC offset str.ADCrate = fix(header, 190) ; 190 ADC rate str.ADCtype = fix(header, 192) ; 192 ADC type str.ADCresolution = fix(header, 194) ; 194 ADC resolution str.ADCbitAdjust = fix(header, 196) ; 196 ADC bit adjust str.gain = fix(header, 198) ; 198 gain temp = byte(header, 200, COMMENTMAX, 5) ; 200 File Comments str.Comments = string(temp) ; 200 File Comments str.geometric = fix(header, 600) ; 600 geometric ops: rotate 0x01, ; reverse 0x02, flip 0x04 temp = byte(header, 602, LABELMAX) ; 602 intensity display string str.xlabel = string(temp) ; 602 intensity display string str.cleans = fix(header, 618) ; 618 cleans str.NumSkpPerCln = fix(header, 620) ; 620 number of skips per clean. str.SpecMirrorPos = fix(header, 622, 2) ; 622 Spectrograph Mirror Positions str.SpecSlitPos = float(header, 626, 4) ; 626 Spectrograph Slit Positions str.AutoCleansActive = fix(header, 642) ; 642 T/F str.UseContCleansInst = fix(header, 644) ; 644 T/F str.AbsorbStripNum = fix(header, 646) ; 646 Absorbance Strip Number str.SpecSlitPosUnits = fix(header, 648) ; 648 Spectrograph Slit Position Units str.SpecGrooves = float(header, 650) ; 650 Spectrograph Grating Grooves str.srccmp = fix(header, 654) ; 654 number of source comp. diodes str.ydim = fix(header, 656) ; 656 y dimension of raw data. str.scramble = fix(header, 658) ; 658 0=scrambled,1=unscrambled str.ContinuousCleansFlag = fix(header, 660) ; 660 T/F Continuous Cleans Timing Option str.ExternalTriggerFlag = fix(header, 662) ; 662 T/F External Trigger Timing Option str.lnoscan = long(header, 664) ; 664 Number of scans (Early WinX) str.lavgexp = long(header, 668) ; 668 Number of Accumulations str.ReadoutTime = float(header, 672) ; 672 Experiment readout time str.TriggeredModeFlag = fix(header, 676) ; 676 T/F Triggered Timing Option str.Spare_2 = byte(header, 678, 10) ; 678 temp = byte(header, FILEVERMAX) ; 688 Version of SW creating this file str.sw_version = string(temp) ; 688 Version of SW creating this file str.type = fix(header, 704) ; 704 0=1000,1=new120,2=old120,3=130, ; st121=4,st138=5,dc131(PentaMax)=6, ; st133(MicroMax)=7,st135(GPIB)=8, ; VICCD=9, ST116(GPIB)=10, ; OMA3(GPIB)=11,OMA4=12 str.flatFieldApplied = fix(header, 706) ; 706 1 if flat field was applied. str.Spare_3 = byte(header, 708, 16) ; 708 str.kin_trig_mode = fix(header, 724) ; 724 Kinetics Trigger Mode temp = byte(header, 726, LABELMAX); 726 Data label. str.dlabel = string(temp) ; 726 Data label. str.Spare_4 = byte(header, 742, 436) ; 742 temp = byte(header, 1178, HDRNAMEMAX) ; 1178 Name of Pulser File with ; Pulse Widths/Delays (for Z-Slice) str.PulseFileName = string(temp) ; 1178 Name of Pulser File with ; Pulse Widths/Delays (for Z-Slice) temp = byte(header, 1298, HDRNAMEMAX) ; 1298 Name of Absorbance File (if File Mode) str.AbsorbFileName = string(temp) ; 1298 Name of Absorbance File (if File Mode) str.NumExpRepeats = long(header, 1418) ; 1418 Number of Times experiment repeated str.NumExpAccums = long(header, 1422) ; 1422 Number of Time experiment accumulated str.YT_Flag = fix(header, 1426) ; 1426 Set to 1 if this file contains YT data str.clkspd_us = float(header, 1428) ; 1428 Vert Clock Speed in micro-sec str.HWaccumFlag = fix(header, 1432) ; 1432 set to 1 if accum done by Hardware. str.StoreSync = fix(header, 1434) ; 1434 set to 1 if store sync used. str.BlemishApplied = fix(header, 1436) ; 1436 set to 1 if blemish removal applied. str.CosmicApplied = fix(header, 1438) ; 1438 set to 1 if cosmic ray removal applied str.CosmicType = fix(header, 1440) ; 1440 if cosmic ray applied, this is type. str.CosmicThreshold = float(header, 1442) ; 1442 Threshold of cosmic ray removal. str.NumFrames = long(header, 1446) ; 1446 number of frames in file. str.MaxIntensity = float(header, 1450) ; 1450 max intensity of data (future) str.MinIntensity = float(header, 1454) ; 1454 min intensity of data (future) temp = byte(header, 1458, LABELMAX) ; 1458 y axis label. str.ylabel = string(temp) ; 1458 y axis label. str.ShutterType = fix(header, 1474) ; 1474 shutter type. str.shutterComp = float(header, 1476) ; 1476 shutter compensation time. str.readoutMode = fix(header, 1480) ; 1480 readout mode, full,kinetics, etc str.WindowSize = fix(header, 1482) ; 1482 window size for kinetics only. str.clkspd = fix(header, 1484) ; 1484 clock speed for kinetics & frame transfer. str.interface_type = fix(header, 1486) ; 1486 computer interface ; (isa-taxi, pci, eisa, etc.) str.NumROIsInExperiment = fix(header, 1488) ; 1488 May be more than the 10 allowed in ; this header (if 0, assume 1) str.Spare_5 = byte(header, 1490, 16) ; 1490 str.controllerNum = fix(header, 1506) ; 1506 if multiple controller system will ; have controller number data came from. ; this is a future item. str.SWmade = fix(header, 1508) ; 1508 Which software package created this file str.NumROI = fix(header, 1510) ; 1510 number of ROIs used. if 0 assume 1. str.ROIinfoblk = replicate({princeton_ROIinfo}, ROIMAX) ; 1512 ROI information NEEDS WORK roioffset = [1512,1524,1536,1548,1560,1572,1584,1596,1608,1620] for i = 0, ROIMAX-1 do begin str.ROIinfoblk[i].startx = fix(header, roioffset[i] + 0) str.ROIinfoblk[i].endx = fix(header, roioffset[i] + 2) str.ROIinfoblk[i].groupx = fix(header, roioffset[i] + 4) str.ROIinfoblk[i].starty = fix(header, roioffset[i] + 6) str.ROIinfoblk[i].endy = fix(header, roioffset[i] + 8) str.ROIinfoblk[i].groupy = fix(header, roioffset[i] + 10) end temp = byte(header, 1632, HDRNAMEMAX) ; 1632 Flat field file name. str.FlatField = string(temp) ; 1632 Flat field file name. temp = byte(header, 1752, HDRNAMEMAX) ; 1752 background sub. file name. str.background = string(temp) ; 1752 background sub. file name. temp = byte(header, 1872, HDRNAMEMAX) ; 1872 blemish file name. str.blemish = string(temp) ; 1872 blemish file name. str.file_header_ver = float(header, 1992) ; 1992 version of this file header str.YT_Info = byte(header, 1996, 1000) ; 1996-2996 Reserved for YT information str.WinView_id = long(header, 2996) ; 2996 == 0x01234567L if in use by WinView offset = 3000 ; 3000 -> 3488 X axis calibration str.xcalibration.offset = double(header, offset) str.xcalibration.factor = double(header, offset+8) str.xcalibration.current_unit = byte(header, offset+16) str.xcalibration.CalibReserved1 = byte(header, offset+17) str.xcalibration.display_string = byte(header, offset+18, 40) str.xcalibration.CalibReserved2 = byte(header, offset+58, 40) str.xcalibration.calib_valid = byte(header, offset+98) str.xcalibration.input_unit = byte(header, offset+99) str.xcalibration.polynounit = byte(header, offset+100) str.xcalibration.polynoorder = byte(header, offset+101) str.xcalibration.calib_count = byte(header, offset+102) str.xcalibration.pixel_position = double(header, offset+103, 10) str.xcalibration.calib_value = double(header, offset+183, 10) str.xcalibration.polynocoeff = double(header, offset+263, 6) str.xcalibration.laser_position = double(header, offset+311) str.xcalibration.CalibReserved3 = byte(header, offset+319) str.xcalibration.leftover_flag = byte(header, offset+320) str.xcalibration.user_label = byte(header, offset+321, 40) str.xcalibration.expansion = byte(header, offset+361, 128) str.ycalibration = {princeton_calibration} offset = 3489 ; 3489 -> 3977 Y axis calibration str.ycalibration.offset = double(header, offset) str.ycalibration.factor = double(header, offset+8) str.ycalibration.current_unit = byte(header, offset+16) str.ycalibration.CalibReserved1 = byte(header, offset+17) str.ycalibration.display_string = byte(header, offset+18, 40) str.ycalibration.CalibReserved2 = byte(header, offset+58, 40) str.ycalibration.calib_valid = byte(header, offset+98) str.ycalibration.input_unit = byte(header, offset+99) str.ycalibration.polynounit = byte(header, offset+100) str.ycalibration.polynoorder = byte(header, offset+101) str.ycalibration.calib_count = byte(header, offset+102) str.ycalibration.pixel_position = double(header, offset+103, 10) str.ycalibration.calib_value = double(header, offset+183, 10) str.ycalibration.polynocoeff = double(header, offset+263, 6) str.ycalibration.laser_position = double(header, offset+311) str.ycalibration.CalibReserved3 = byte(header, offset+319) str.ycalibration.leftover_flag = byte(header, offset+320) str.ycalibration.user_label = byte(header, offset+321, 40) str.ycalibration.expansion = byte(header, offset+361, 128) temp = byte(header, 3978, 40) ; 3978 special intensity scaling string Istring = string(temp) ; 3978 special intensity scaling string str.Spare_6 = byte(header, 4018, 76) ; 4018 str.AvGainUsed = fix(header, 4094 ) ; 4094 str.AvGain = fix(header, 4096 ) ; 4096 str.lastvalue = fix(header, 4098) ; 4098 Always the LAST value in the header ; 4100 Bytes Total Header Size ; If this is a big-endian machine swap the byte order ; I don't know of a built-in IDL test for endianness, do it ourselves t1 = 1 t2 = 1 byteorder, t2, /sswap, /swap_if_big_endian big_endian = (t1 ne t2) if (big_endian) then str = swap_endian(str) return, str end