esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% marcollect.mac
#%NAME% 
#   Data collection macro with MAR Scanner and spindle/shutter
#   synchronisation (VCT6).
#
#%CATEGORY% Detection
#
#%DESCRIPTION%
#   The MAR345 scanner provides a X-ray detection area from 180 to 345 mm with two possible
#   pixel sizes 100 and 150 micro-meter. This scanner is using a unique image-plate that is
#   erased after each exposure-read-out cycle. This is why the mar is used as detector  and
#   not as a offline scanner. 
#   Read-out cycles range from 108 to 34 (!!!) seconds, depending on pixel size and scanned
#   plate diameter. This is about 3 times faster than other scanners and actually comes 
#   close to the performance of CCD-detectors.
#%BR%
#    a TACO device server named MarScan345ds is running on the MAR computer and
#    controls the scanner. 
#
#%OVERVIEW%
#%BR%
#   These user macros allow full control of the scanner for doing single scan, enabling spec scan with the mar like pseudo-counter or starting a data collection with spindle/shutter synchronisation. 
#%DL%
#%DT%marsetup%DD%  setup  the mar scanner
#%DT%marcollect%DD%  Perform a data collection

#%XDL%
#
#%LOG%
#$Log: marcollect.mac,v $
#Revision 1.2  2008/08/12 13:24:58  rey
#documentation changes
#
#Revision 1.1  2005/03/31 13:19:27  claustre
#Initial revision
#
#
#                     
#%END%

#%UU% [ccd device number]
#%MDESC%
#   Has to be called first with ccd-device-number as defined into the spec
#   configuration.
def marsetup '{

   global MAR_NUM MAR_DEV MARHOME MAR_SCANHOME
   global MAR_DISABLED MAR_CMDID
   global MAR_FORMAT
   global MAR_SCANDATADIR MAR_DATADIR MAR_IMAGEDIR MAR_SUFFIX
   global MAR_N MAR_FILEPREFIX MAR_PREFIX MAR_OVRW
   global MAR_COLLECT 
   global MAR_DIST MAR_WAV

   if (whatis("MAR_DEV") & 0x8000000) {
      MAR_DEV = "ID9/mar345/111"      
   }

   if ($#){
      MAR_NUM		= $1
      
   }else {
      MAR_NUM=getval("CCD Device number (from spec config)",MAR_NUM)
   }
   #
   # Check that the server is running 
   #
   if (image_par(MAR_NUM,"controller") != "SCANNER" ) {
        print "CCD Device "MAR_NUM" is not a MAR SCANNER"
        print "Please, check with ccdmenu a scanner is well configured!"
        exit
   }
   MAR_DEV = image_par(MAR_NUM,"device_id")         
}'

#%UU%
#%MDESC%
#
# Set new file parameters. 
#
def marnewfile '{

 print "Please enter:"
 MAR_N   = getval("   - Image number:     ",MAR_N)
 MAR_IMAGEDIR   = getval("   - Data directory on the MAR computer:   ",MAR_IMAGEDIR) 
 MAR_PREFIX     = getval("   - Prefix for files: ",MAR_PREFIX)
 MAR_OVRW       =  yesno("   - Overwrite existing file: (y/n)", MAR_OVRW)
 mar_filepar()
}'

#%UU%
#%MDESC%
#
# Set image parameters, detector distance and wavelength
#
def marimagepar '{

 print "Please enter:"
 MAR_DIST   = getval("   - Detector Distance (mm): ",MAR_DIST)
 MAR_WAV    = getval("   -  Wavelength (A):        ",MAR_WAV) 
 mar_imagepar()
}'

def mar_imagepar() '{
  local mar_impar
  mar_impar = sprintf("opt_distance=%f opt_wavelength=%f", MAR_DIST, MAR_WAV)
  return esrf_io(MAR_DEV, "DevScannerSetOptPar", mar_impar)
}'

#%IU%
#%MDESC%
#
# internal function that really set the new file parameters. 
# return -1 if the esrf_io failed
def mar_filepar() '{

  local mar_par
  
  mar_par[0] = MAR_IMAGEDIR
  mar_par[1] = MAR_PREFIX
  mar_par[2] = sprintf("%d",MAR_N)
  mar_par[3] = "%03d"
  mar_par[4] = (MAR_OVRW)?"y":"n"

  return esrf_io(MAR_DEV, "DevScannerSetFilePar", mar_par)
}'

#%IU%
#%MDESC%
#
# internal function that reset the current filename setting 
# return -1 if the esrf_io failed
def mar_getfilename() '{

  local mar_par
  local mar_format
  local mar_mode

  mar_par[0] = MAR_IMAGEDIR
  mar_par[1] = MAR_PREFIX
  mar_par[2] = sprintf("%d",MAR_N)
  mar_par[3] = "%03d"
  mar_par[4] = (MAR_OVRW)?"y":"n"

  if (esrf_io(MAR_DEV, "DevScannerGetFilePar", mar_par)==-1) return -1
  if ((mar_mode=esrf_io(MAR_DEV, "DevScannerGetMode"))==-1) return -1
  if ((mar_format=esrf_io(MAR_DEV, "DevScannerGetFormat"))==-1) return -1

  MAR_N = mar_par[0]
  MAR_PREFIX = mar_par[1]
  sscanf(mar_par[2],"%d",MAR_N)
  MAR_OVRW = (mar_par[4]=="Y")?1:0
  MAR_SUFFIX = (mar_format==0)? "mar":((mar_format==1)? "image": "s")
  if (mar_format == 0) MAR_SUFFIX = sprintf("%s%d", MAR_SUFFIX, mar_mode)

  return sprintf("%s/%s%03d.%s", MAR_IMAGEDIR, MAR_PREFIX, MAR_N, MAR_SUFFIX)
}'



def marshow '{
    printf("\n\n<MAR345> Collect Settings   ____________\n\n")
    printf("  Filename prefix:               %s\n", MAR_FILEPREFIX)
    printf("  Number of Frames:              %d\n", MAR_NOIMGS)
    printf("  Number of Passes:              %d\n", MAR_NOPASSES)
    printf("  Rotation Oscillation (degree): %f\n", MAR_OSCILLATION)
    printf("  Oscillation overlap (degree):  %f\n", MAR_OVERLAP)
    printf("  Exposure time per pass(s):     %f\n", MAR_EXPOSTIME)
    printf("  Starting Angle (degree):       %f\n", MAR_STARTANGLE)
    printf("  Data Directory:                %s\n", MAR_IMAGEDIR)
    printf("  Overwrite existing file:       %s\n", MAR_OVRW?"Yes":"No")
    printf("  Erase:                         %s\n", MAR_ERASE?"Yes":"No")
    printf("________________________________________\n\n")
}'

def mar_getvals '{
    MAR_FILEPREFIX    = getval("  * Filename prefix:       ", MAR_FILEPREFIX)
    MAR_NOIMGS        = getval("  * Number of Frames:      ", MAR_NOIMGS)
    MAR_NOPASSES      = getval("  * Number of Passes:      ", MAR_NOPASSES)
    MAR_OSCILLATION   = getval("  * Rotation Oscillation (degree): ", \
                                  MAR_OSCILLATION)
    MAR_OVERLAP       = getval("  * Oscillation overlap (degree):  ", \
                                  MAR_OVERLAP)
    MAR_EXPOSTIME     = getval("  * Exposure time (s):             ", \
                                  MAR_EXPOSTIME)
    MAR_STARTANGLE    = getval("  * Starting Angle (degree):       ", \
                                  MAR_STARTANGLE )
    MAR_IMAGEDIR      = getval("  * Data Directory:                ", \
                                  MAR_IMAGEDIR)
    MAR_OVRW          = yesno("  * Overwrite existing file :       ", \
				  MAR_OVRW)
    MAR_ERASE         = yesno("  * Erase data after scan :         ", \
				  MAR_ERASE)
}'

#%UU% ["filename prefix"] ["frames number"] ["passes number"] ["oscillation range"] ["oscillation overlap"] ["exposure time"] ["starting position"] ["image directory"] ["erase first"]

#%MDESC%
#     Performs the data collection. will acquire [frames number] images
#     into the ["image directory"] directory with the file names 
#     ["filename prefix"]_$$ (where $$ is from [starting frame number]
#     to [starting frame number]+[frames number]. The first position
#     will be [starting position], the angle oscillation for each frame
#     is [oscillation range] and there will be [passes number] passes for
#     each frame in [exposure time] seconds.
def marcollect '{
    global MAR_NOIMGS MAR_NOPASSES MAR_ERASE
    global MAR_OSCILLATION MAR_OVERLAP MAR_EXPOSTIME
    global MAR_STARTANGLE

    MAR_COLLECT = 1


    if ($#) {
        MAR_FILEPREFIX    = "$1"
        MAR_NOIMGS        =  $2
        MAR_NOPASSES      =  $3
        MAR_OSCILLATION   =  $4
        MAR_OVERLAP       =  $5
        MAR_EXPOSTIME     =  $6
        MAR_STARTANGLE    =  $7
        MAR_IMAGEDIR      = "$8"
        MAR_OVRW          = "$9"
        MAR_ERASE         = "$10"
    } else {
        inloop = 1
	while(inloop) {
	    marshow
	    _yn=yesno("Do you want to change these settings",0)
	    if (_yn) {
	       mar_getvals
            } else {
               inloop = 0
            }
        }
    }

    if (MAR_NOPASSES == 0) {
	 MAR_NOPASSES = 1
    }

    MAR_N = 0   # always 0

    MAR_PREFIX = sprintf("%s_%03d_",MAR_FILEPREFIX,SCAN_N+1)

    #
    # Test if the file parameters are valid
    #
#    MAR_DATADIR     = sprintf("%s/%s",MARHOME,MAR_IMAGEDIR)

    if (mar_filepar() == -1 ) {
       printf("   <MAR345> Invalid parameters\n")
       exit
    }

    HEADING = "marcollect " MAR_FILEPREFIX " " MAR_NOIMGS " " MAR_NOPASSES  
    HEADING = HEADING " " MAR_OSCILLATION " " MAR_OVERLAP " " MAR_EXPOSTIME
    HEADING = HEADING " " MAR_STARTANGLE " " MAR_IMAGEDIR " " MAR_ERASE

    mname = motor_name(motor_num(PHI_MOTOR_NAME))
    FPRNT=sprintf("Frame_no  %s  ",mname)
    VPRNT=sprintf("%9.9s ",mname)

    scan_head

    mar_loop_frames() 
    cdef("","","_phiosc_","delete")
}'

def mar_head '{
     HEADING="marcollect $*"
     scan_head
}'

#%IU%
#%MDESC%
#
def mar_loop_frames() '{

 local curr_frame curr_pass start_angle stop_angle expo_time
 
 curr_frame = 0
 curr_pass = 0

 while ( curr_frame < MAR_NOIMGS) {

     if (MAR_ERASE) {
         marerase
     }

     start_angle = MAR_STARTANGLE + (curr_frame * (MAR_OSCILLATION-MAR_OVERLAP))
     stop_angle  = start_angle + MAR_OSCILLATION 
     expo_time   = MAR_EXPOSTIME

     waitmove; get_angles

     VFMT="%3.4f "
     FPRNT=sprintf("%.8g ",start_angle)
     VPRNT=sprintf(VFMT,start_angle)

     tty_cntl("md")
     sp = sprintf("      Frame % 3d: ", MAR_N)
     tty_cntl("me")
     sp = sp sprintf("%3.2f -> %3.2f ",start_angle,stop_angle) 

     #
     # While statement to make the passes for each frame
     #
     curr_pass = 0

     for ( i = 0;i<COUNTERS;i++) {
         MAR_CNT[i] = 0
     }


     while (curr_pass < MAR_NOPASSES) {
          tty_cntl("md")
          printf("%s => Pass %d       \r", sp,curr_pass+1)
          tty_cntl("me")

          phi_oscillation start_angle stop_angle expo_time
 
          curr_pass++

	  getcounts

          for ( i = 0;i<COUNTERS;i++) {
	      if (counter_par(0,"controller")  != "NONE")
                 MAR_CNT[i] += S[i]
              else		  
                 MAR_CNT[i] += S_saved[i]
          }
     } 

     for ( i = 0;i<COUNTERS;i++) {
        S[i] = MAR_CNT[i] 
     }

     cdef("","","_phiosc_","delete")
  
     marscan

     MAR_N++; curr_frame ++
     mar_dataloop
  }
}'

def mar_dataloop '{
     local n

     n = int((COLS - length(VPRNT) - length(Pout) - 24) / 9)

     s = sprintf("%3d %s%g ", NPTS,VPRNT,S[DET])

     NPTS++

     if (MON >= 0) {
          s = s sprintf("%g ", S[MON])
          n--
     }

     s = s sprintf("%10.6g ",S[sec])

     for (i=0; i<COUNTERS && n>0; i++) {
         if (i!=DET && i !=MON && i!=sec && is_using_counter(i)) {
              s = s sprintf("%8.4g ", S[i])
              n--
         }
     }

     printf("%s%s\n",s,Pout)

     if (DATAFILE != "") {
          fprintf(DATAFILE,"%d %s%s%d",NPTS,FPRNT,Fout,(TIME_END=time())-EPOCH)
          for (i=0;i<COUNTERS;i++)
                if (i != MON && i != DET && is_using_counter(i))
                       fprintf(DATAFILE," %g",S[i])
          fprintf(DATAFILE," %g",S[MON])
          fprintf(DATAFILE," %g\n",S[DET]);
     }

}'

#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
# The file(s) marcollect.mac, ccd.mac and oscil.mac have to be read in
#%AUTHOR% L.Claustre / V.Rey, 1997-2005
#$Revision: 1.2 $ 
#%TOC%