diff --git a/documentation/areaDetector.html b/documentation/areaDetector.html new file mode 100755 index 0000000..8163496 --- /dev/null +++ b/documentation/areaDetector.html @@ -0,0 +1,158 @@ + +
+Module Owner: Mark Rivers: University of Chicago
+ +This page is the home of areaDetector, an application for controlling area (2-D) +detectors, including CCDs, pixel array detectors, and online imaging plates. + +
+NOTE: This module will replace the +ccd +and +pilatusROI +modules. +
+ +Devices supported in areaDetector include:
+ +From Dectris +
From Prosilica +
From MAR
+From Roper
+From Bruker
+Please email any comments and bug reports to Mark +Rivers who is +responsible for coordinating development and releases.
+ +You can download the software from the links in the table +below:
+| Module Version | +Release Date | +Filename | +Documentation | +Release Notes | +Known Problems | +
|---|---|---|---|---|---|
| 1-0beta1 | +21-Mar-2008 | +areaDetectorHEAD.tgz | +areaDetectorDoc | +Release notes | +See release notes | +
| Module Version | +Requires module | +Release needed | +Required for | +
|---|---|---|---|
| 1-0beta | +EPICS base | +3.14.8.2 | +Base support | +
| asyn | +4-10 | +Socket and interface support | +|
| sscan | +2-5-6 | +Busy record | +|
| autosave | +4-3 | +Save/restore | +
After obtaining a copy of the distribution, it must be installed +and built for use at your site. These steps only need to be +performed once for the site (unless versions of the module running +under different releases of EPICS and/or the other required modules +are needed).
+tar xvzf areaDetectorRX-Y.tgz + ++where X-Y is the release.
.../support/areaDetectorRX-Y +
+ +
+ +
+The areaDetector module provides a general-purpose interface for area (2-D) detectors in EPICS. +It is intended to be used with a wide variety of detectors and cameras, ranging from high frame rate +video cameras, pixel-array detectors such as the Pilatus, and large format detectors like the +MAR-345 online imaging plate.
+ +The goals of this module are: ++ +
+The architecture of the areaDetector module is shown in Figure 1. + +

pilatusROI.st.
+ This program implements all of the logic for acquiring images, reading
+ the TIFF files, computing ROIs, and making the data available to EPICS.
+ pilatusROI.template, pilatusROI_N.template.
+ These databases
+ contain almost no "logic" with no links between records in the database.
+ Some of the records use "streamDevice" for communication with camserver. Other
+ records are simply variables which channel access clients and the State
+ Notation Language (SNL) program use.
+ pilatusROI.protocol.
+ This file defines the protocol used for
+ communicating with camserver.
+ pilatusROI_settings.req, pilatusROI_N_settings.req.
+ These files define the EPICS PVs
+ that will be automatically saved and restored when the EPICS IOC is restarted, so that
+ state information is preserved.
+ pilatusROI.adl,
+ pilatus8ROIs.adl, pilatusROI_waveform.adl. These screens are
+ used to control image acquisition, and definition and display of ROI data.
+ epics_image_display.pro for displaying the images
+ as they are sent to EPICS. This program is also available as a pre-built IDL ".sav" file
+ that can be run for free under the IDL Virtual Machine.
+ + +
+The following EPICS records are used by pilatusROI. All records are prefixed by the macro +$(DET) which must be passed to the template file when the records are loaded.
+AcquireMode (mbbo)MinImageUpdateTime PV is ignorred in
+ this mode, so that all images are sent to EPICS for display.
+ It is similar to the exposem command in TVX.
+ Exposure,
+ ExtEnable, ExtTrigger, and ExtMTriggerrespectively.
+ Alignment mode uses the Exposure command as well, but continuously takes images into
+ the same temporary file (alignment.tif).
+ ExposureTime (ao)NImages (longout)ExposurePeriod (ao)NExposures (longout)DelayTime (ao)Acquire (busy)Armed (bo)Abort (bo)StatusMessage (stringout)+
ThresholdEnergy (ao)Gain (mbbo)+
FilePath (waveform, FTVL=UCHAR, NELM=256)+ This record is an EPICS waveform record with FTVL=UCHAR and NELM=256. + This removes the 40 character + restriction on path name lengths that arise if an EPICS "string" PV is used. medm allows one to + edit and display such records correctly. EPICS clients will typically need to convert the path + name from a string to an integer or byte array before sending the path name to EPICS. This is easy + to do in clients like SPEC, Matlab, and IDL. +
Filename (stringout)FileNumber (longout)FileFormat (stringout)+ epicsSnprintf(FullFilename, sizeof(FullFilename), FileFormat, + FilePath, Filename, FileNumber); ++ FilePath, Filename, FileNumber are converted in that order with FileFormat. + The default file format is
"%s%s%4.4d.tif". The first %s converts the FilePath,
+ followed immediately by another %s for Filename.
+ FileNumber is formatted with %4.4d, which results in a
+ fixed field with of 4 digits, with leading zeros as required. Finally, the .tif extension
+ is added to the file name. This will make camserver save files in TIFF format with that extension.
+ + This mechanism for creating file names is very flexible. Other characters, such as _ can be put + in Filename or FileFormat as desired. If one does not want to have FileNumber in the file name + at all, then just omit the %d format specifier from FileFormat. +
+ Note that when saving multiple images (NImages>1) camserver has its own rules for creating the + names of the individual files. The rules are as follows: +
+ The name constructed using the above algorithm is used as a basename. + The following examples show the interpretation of the basename. +
+ Basename Files produced + + test6.tif test6_00000.tif, test6_00001.tif, ... + test6_.tif test6_00000.tif, test6_00001.tif, ... + test6_000.tif test6_000.tif, test6_001.tif, ... + test6_014.tif test6_014.tif, test6_015.tif, ... + test6_0008.tif test6_0008.tif, test6_0009.tif, ... + test6_2_0035.tif test6_2_0035.tif, test6_2_0036.tif, ... ++ + The numbers following the last '_' are taken as a format template, + and as a start value. The minimum format is 3; there is no maximum; the + default is 5. The format is also constrained by the requested number of images. +
AutoIncrement (bo)FullFilename (waveform, FTVL=UCHAR, NELM=256)ROI$(N)XMin (longout)ROI$(N)XMax (longout)ROI$(N)YMin (longout)ROI$(N)YMax (longout)ROI$(N)BgdWidth (longout)ROI$(N)TotalCounts (ao)ROI$(N)NetCounts (ao)ROI$(N)MinCounts (longout)ROI$(N)MaxCounts (longout)ROI$(N)Label (stringout)ROI$(N)WFTotalCounts (waveform, FTVL=DOUBLE, NELM=$(NCHANS))ROI$(N)WFNetCounts (waveform, FTVL=DOUBLE, NELM=$(NCHANS))MinWFUpdateTime (ao)ImageData (waveform, FTVL=LONG, NELM=$(NPIXELS))NXPixels (longout)NYPixels (longout)HighlightROIs (bo)PostImages (bo)MinImageUpdateTime (ao)BadPixelFile (waveform, FTVL=UCHAR, NELM=256)+ badX1,badY1 replacementX1,replacementY1 + badX2,badY2 replacementX2,replacementY2 + ... ++ The X and Y coordinates range from 0 to NXPixels-1 and NYPixels-1. Up to 100 bad pixels can be defined. + The bad pixel mapping simply replaces the bad pixels with another pixel's value. + It does not do any averaging. It is felt that this is sufficient for the purpose for which + pilatusROI was written, namely fast on-line viewing of ROIs and ImageData. More sophisticated + algorithms can be used for offline analysis of the image files themselves. + The following is an example bad pixel file for the GSECARS detector: +
+ 263,3 262,3 + 264,3 266,3 + 263,3 266,3 + 300,85 299,85 + 300,86 299,86 + 471,129 472,129 ++
NBadPixels (longout)FlatFieldFile (waveform, FTVL=UCHAR, NELM=256)+ ImageData[i] = (averageFlatField * ImageData[i])/flatField[i]; ++
MinFlatField (ao)FlatFieldValid (bo)ReadTiffTimeout (ao)SendMessage (waveform, FTVL=UCHAR, NELM=256)ReplyMessage (waveform, FTVL=UCHAR, NELM=256)Connect (bo)Disconnect (bo)scan1, scan2, scan3, scan4, scanH (sscan)+ +
+pilatusROI.template is loaded with the following macro parameters: +
| Macro parameter | +Description | +
|---|---|
$(DET) |
+ PV name prefix. This identifies this Pilatus detector from others that may be + running on the same subnet. + | +
$(NXPIXELS) |
+ The number of pixels in the X (fast index) direction on the detector. This is 487 for the Pilatus 100K. | +
$(NYPIXELS) |
+ The number of pixels in the Y (slow index) direction on the detector. This is 195 for the Pilatus 100K. | +
$(NPIXELS) |
+ The total number of pixels on the detector. This is NXPIXELS*NYPIXELS=94965 for the Pilatus 100K. | +
$(PORT) |
+ The name of the asyn port connected to the Pilatus via a TCP/IP socket. | +
+pilatusROI_N.template is loaded for each ROI with the following macro parameters: +
| Macro parameter | +Description | +
|---|---|
$(DET) |
+ PV name prefix. This identifies this Pilatus detector from others that may be + running on the same subnet. | +
$(N) |
+ The number of this ROI. Starts with 1. | +
$(XMIN) |
+ The minimum value of X for this ROI. Starts with 0. | +
$(XMAX) |
+ The maximum value of X for this ROI. Starts with 0. | +
$(YMIN) |
+ The minimum value of Y for this ROI. Starts with 0. | +
$(YMAX) |
+ The maximum value of Y for this ROI. Starts with 0. | +
$(BGD_WIDTH) |
+ The background width for this ROI. + If BGD_WIDTH <=0 then no background subtraction is done, and NetCounts=TotalCounts. | +
$(NCHANS) |
+ The maximum number of elements in the WFTotalCounts and WFNetCounts waveform arrays. + This sets the maximum value of NImages for collecting ROI arrays. | +
+The pilatusROIs SNL program is started with the following macro parameters: +
| Macro parameter | +Description | +
|---|---|
DET |
+ PV name prefix. This identifies this Pilatus detector from others that may be + running on the same subnet. | +
PORT |
+ The name of the asyn port connected to the Pilatus via a TCP/IP socket. | +
NROIS |
+ The number of ROIs loaded in the substitutions file with pilatusROI_N.template. + Maximum=32. | +
+The following is an example st.cmd startup script: +
+< envPaths
+
+###
+# Load the EPICS database file
+dbLoadDatabase("$(PILATUS)/dbd/pilatus.dbd")
+pilatus_registerRecordDeviceDriver(pdbbase)
+
+###
+# Create the asyn port to talk to the Pilatus on port 41234.
+drvAsynIPPortConfigure("pilatus","gse-pilatus1:41234")
+# Set the input and output terminators.
+asynOctetSetInputEos("pilatus", 0, "\030")
+asynOctetSetOutputEos("pilatus", 0, "\n")
+# Define the environment variable pointing to stream protocol files.
+epicsEnvSet("STREAM_PROTOCOL_PATH", "$(PILATUS)/pilatusApp/Db")
+
+###
+# Specify where save files should be
+set_savefile_path(".", "autosave")
+
+###
+# Specify what save files should be restored. Note these files must be
+# in the directory specified in set_savefile_path(), or, if that function
+# has not been called, from the directory current when iocInit is invoked
+set_pass0_restoreFile("auto_settings.sav")
+set_pass1_restoreFile("auto_settings.sav")
+
+###
+# Specify directories in which to to search for included request files
+set_requestfile_path("./")
+set_requestfile_path("$(AUTOSAVE)", "asApp/Db")
+set_requestfile_path("$(CALC)", "calcApp/Db")
+set_requestfile_path("$(SSCAN)", "sscanApp/Db")
+set_requestfile_path("$(PILATUS)", "pilatusApp/Db")
+
+###
+# Load the save/restore status PVs
+dbLoadRecords("$(AUTOSAVE)/asApp/Db/save_restoreStatus.db", "P=PILATUS:")
+
+###
+# Load the substitutions for for this IOC
+dbLoadTemplate("PILATUS_all.subs")
+# Load an asyn record for debugging
+dbLoadRecords("$(ASYN)/db/asynRecord.db", "P=PILATUS:,R=asyn1,PORT=pilatus,ADDR=0,IMAX=80,OMAX=80")
+
+# Load sscan records for scanning
+dbLoadRecords("$(SSCAN)/sscanApp/Db/scan.db", "P=PILATUS:,MAXPTS1=2000,MAXPTS2=200,MAXPTS3=20,MAXPTS4=10,MAXPTSH=2048")
+
+###
+# Set debugging flags if desired
+#asynSetTraceIOMask("pilatus",0,2)
+#asynSetTraceMask("pilatus",0,3)
+
+###
+# Start the IOC
+iocInit
+
+###
+# Save settings every thirty seconds
+create_monitor_set("auto_settings.req", 30, "P=PILATUS:")
+
+###
+# Start the SNL program
+seq(pilatusROIs, "DET=PILATUS:, PORT=pilatus, NROIS=16")
+
+
+The following is the substutitions file PILATUS_all.subs referenced above.
+It creates 16 ROIS, and defines 5 valid ones: the entire chip, and the 4 quadrants of the chip:
+
+ffile $(PILATUS)/db/pilatusROI.template {
+pattern
+{DET, NXPIXELS, NYPIXELS, NPIXELS, PORT}
+{PILATUS:, 487, 195, 94965, pilatus}
+}
+
+file $(PILATUS)/db/pilatusROI_N.template {
+pattern
+{DET, N, XMIN, XMAX, YMIN, YMAX, BGD_WIDTH, NCHANS}
+{PILATUS:, 1, 0, 486, 0, 194, 1, 2000}
+{PILATUS:, 2, 0, 243, 0, 97, 1, 2000}
+{PILATUS:, 3, 0, 243, 98, 194, 1, 2000}
+{PILATUS:, 4, 244, 486, 0, 97, 1, 2000}
+{PILATUS:, 5, 244, 486, 98, 194, 1, 2000}
+{PILATUS:, 6, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 7, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 8, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 9, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 10, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 11, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 12, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 13, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 14, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 15, -1, -1, -1, -1, 1, 2000}
+{PILATUS:, 16, -1, -1, -1, -1, 1, 2000}
+}
+
+
++ +
+The following show the MEDM screens that are used to control the pilatusROI software.
+ ++ +
pilatusROI.adl is the main screen used to control the pilatusROI SNL
+program. All records except those that are specific to each ROI are accessed through this
+screen.
+
+ +
pilatus8ROIs.adl is used to define the ROIs, and to display the statistics for
+each ROI. In this example there are 2 valid ROIs defined. ROI 1 is a small rectangle near the center
+containing the Bragg diffraction peak from a crystal. ROI 2 is the entire chip.
+
+ +
pilatusROI_waveform.adl is used to plot the net or total counts in an ROI when
+NImages>1. In this example the plot is the net counts in ROI 1 as the diffractometer chi was scanned
++- 1 degree with 1000 points at .02 seconds/point. This was done with the SPEC command
++lup chi -1 1 1000 .02 ++using trajectory scanning on a Newport kappa diffractometer. This was a compound motor scan with the +Newport XPS putting out pulses every .02 seconds. These pulses triggered the Pilatus in External Enable mode. +The pilatusROI program read each TIFF file as it was created and updated this plot every 0.2 seconds. +The total time to collect this scan with 1000 images was 20 seconds. +

+ +
scan_more.adl is used to define a scan. In this example the sscan record is set up
+to scan the ThresholdEnergy PV and to collect the total counts in ROI2, which was defined to include
+the entire detector.
+
+ +
scanDetPlot.adl is used to plot the results of a scan after it is complete.
+In this example the total counts in ROI 2 are plotted as a function of the ThresholdEnergy as it was
+scanned from 3000 to 10000 eV in 250 eV steps. The source was Fe55, and the cut-off is at 6 keV, as
+expected for the Mn Ka and Mn Kb x-rays that this source produces.
+
+ +
asynRecord.adl is used to control the debugging information printed by the asyn TCP/IP driver
+(asynTraceIODriver) and the SNL program (asynTraceIODevice).
+
+ +
asynOctet.adl can be used to send any command to camserver and display the response. It can
+be loaded from the More menu in asynRecord.adl above.
+
+ +
epics_image_display
+that can be used to display the ImageData PV that pilatusROI sends over EPICS. This IDL
+client is available as source code (which requires an IDL license), and also as a pre-built IDL .sav
+file that can be run for free under the IDL Virtual Machine. This IDL program can run on any machine that IDL
+runs on, and that has the ezcaIDL shareable library built for it. This includes Windows, Linux, Solaris, and Mac.
+epics_image_display is included in the
+CARS IDL imaging software.
+
+
+The control window for epics_image_display is shown below. It has fields to input the name of
+the EPICS PV with the image data, which is $(DET)ImageData in the case of pilatusROI. It also has fields
+for the number of pixels in the X and Y directions. This is needed because EPICS waveform records are
+1-dimensional only, and so do not contain the information on the number of rows and columns in the image.
+
+

+ +
epics_image_display uses the routine
+image_display.pro
+to display the images. This routine displays row and column profiles as the cursor is moved. It allows
+changing the color lookup tables, and zooming in and out with the left and right mouse buttons. The following
+is an example of image_display displaying a Pilatus image with an Fe55 source in front of the detector.
+
+
+ +
+# need some more globals (kludge)
+global PILATUS_ROI_PV
+global PILATUS_IMGPATH_PV
+global PILATUS_FNAME_PV
+global PILATUS_FILENUMBER_PV
+global PILATUS_FILEFORMAT_PV
+global PILATUS_EXPSRTM_PV
+global PILATUS_NFRAME_PV
+global PILATUS_EXPPRD_PV
+global PILATUS_NEXPFRM_PV
+global PILATUS_ACQ_PV
+global PILATUS_ACQMODE_PV
+
+###############################################################
+def _setup_img '{
+ local j, str
+
+ # PILATUS_PREFIX should be detector aquisition pv (GSE-PILATUS1:)
+ if ( PILATUS_PREFIX == "") PILATUS_PREFIX = "GSE-PILATUS1:"
+ PILATUS_PREFIX = getval("Enter PILATUS pv prefix",PILATUS_PREFIX)
+
+ # rois pvs
+ PILATUS_ROI_PV = PILATUS_PREFIX "ROI1NetCounts"
+ PILATUS_IMGPATH_PV = PILATUS_PREFIX "FilePath"
+ PILATUS_FNAME_PV = PILATUS_PREFIX "Filename"
+ PILATUS_FILENUMBER_PV = PILATUS_PREFIX "FileNumber"
+ PILATUS_FILEFORMAT_PV = PILATUS_PREFIX "FileFormat"
+ PILATUS_EXPSRTM_PV = PILATUS_PREFIX "ExposureTime"
+ PILATUS_NFRAME_PV = PILATUS_PREFIX "NImages"
+ PILATUS_EXPPRD_PV = PILATUS_PREFIX "ExposurePeriod"
+ PILATUS_NEXPFRM_PV = PILATUS_PREFIX "NExposures"
+ PILATUS_ACQ_PV = PILATUS_PREFIX "Acquire"
+ PILATUS_ACQMODE_PV = PILATUS_PREFIX "AcquireMode"
+...
+
+def epics_pilatus_count '{
+...
+ # write to data base fields
+ # Need to convert path from string to byte array
+ # Note: we use the "wait" parameter in epics_put here (new to spec5.7.02) so that
+ # it uses ca_put_callback, to know that all PVs have been processed
+ # before we start counting. Use 1 second timeout, will actually be
+ # much faster than this unless something is wrong.
+ array _temp[256]
+ _temp = PILATUS_IMAGE_DIR
+ # Do not change path for now
+ #epics_put(PILATUS_IMGPATH_PV,_temp, 1)
+ epics_put(PILATUS_FNAME_PV,img_fname, 1)
+ epics_put(PILATUS_FILENUMBER_PV,NPTS, 1)
+ epics_put(PILATUS_FILEFORMAT_PV,_fileformat, 1)
+ epics_put(sc_prtm_pv,cnt_time_val, 1)
+ epics_put(PILATUS_EXPSRTM_PV,cnt_time_val, 1)
+ epics_put(PILATUS_ACQMODE_PV,0, 1) # Internal trigger
+ epics_put(PILATUS_NFRAME_PV, 1, 1)
+ epics_put(PILATUS_NEXPFRM_PV, 1, 1)
+
+
+def user_getcounts '{
+ local pv_roi, j, pv
+
+...
+ # using image_count routine
+ } else if ( EPICS_COUNT == 4 ) {
+ S[iroi] = 0
+ S[iroi] = epics_get(PILATUS_ROI_PV)
+
+
++ +
+ lup chi -2 2 1000 .015 ++ This tells SPEC to do a relative scan of the chi axis from -2 degrees to +2 degrees with 1000 points + at .015 seconds/point. On our kappa diffractometer this entails a coordinated motion of the phi, kappa + and omega axes. The EPICS trajectory scanning software downloads the non-linear trajectory that SPEC computes + into the XPS controller, which executes it. As the motors are moving the XPS outputs synchronization pulses + at the period of the collection time, .015 seconds in this case. These pulses are stretched + (see Hardware notes below) and used as the external input to the Pilatus. + The time to execute this scan should be 15.0 seconds. The actual time was 16.3 seconds, measured + using camonitor on the Acquire PV. Again, this includes the time for camserver to save all 1000 images to disk + (366 MB), and for pilatusROI to read each file, correct the bad pixels and flat field, compute the ROIs, and post the ROIs + to EPICS. It also posted the images to EPICS at 1Hz (15 images total). The total additional time was less + than 1.3 seconds for all 1000 images. As soon as the acquisition was complete SPEC plotted the net counts in + the first ROI (containing the Bragg peak) as follows: +

+ For comparison this identical scan was executed in traditional step-scanning mode, where the motors stopped + at each point in the scan. The Pilatus was run in Internal mode with NImages=1. The total time for the scan + was 870 seconds (more than 14 minutes), compared to 16.3 seconds in trajectory mode. Most of this overhead + is the settling time for the motors, with only a small fraction due to the Pilatus single-exposure mode. The + trajectory scanning mode is thus more than 50 times faster to execute the identical SPEC scan. +
+ +
In External Enable mode (the camserver ExtEnable command) the Pilatus uses the external signal to control acquisition. +Only NImages and NExposures are used, ExposureTime and ExposurePeriod are not used. When the signal +is high the detector counts, and on the transition to low it begins its readout. + +
In External MultiTrigger Mode (the camserver ExtMTrigger command) the Pilatus uses the programmed ExposureTime, +in addition to NImages and NExposures. Each external trigger pulse causes the Pilatus to collect one image +at the programmed exposure time. This mode works well with a trigger source like the Newport motor controllers +or the SIS380x multichannel scaler, +that put out a short trigger pulse for each image. One only needs to take care that the time between external trigger +pulses is at least 4msec longer than the programmed exposure time, to allow time for the detector to read out before +the next trigger pulse arrives. + +
When using the External Enable mode, we use an inexpensive analog pulse generator +to convert the trigger pulses from the MM4005 and XPS to a form suitable for External Enable mode +with the Pilatus. This is the solution we have developed that seems to be reliable: +
+Dectris has since informed me that they have increased the power supply voltage on all new Pilatus systems, +so this should no longer be an issue. + + +
+ +