#! /usr/bin/env python
# Federica Marone, July 2, 2014

import time
import sys
import math
import os
import ca
import CaChannel
import xml.etree.ElementTree as ET

sys.path.append("/work/sls/bin")

from epicsPV import epicsPV
from epicsMotor import epicsMotor
from channelDefinition import * 

CaChannel.CaChannel.ca_timeout = 3
# ------------------------ Functions -------------------------------------
def show_help():
	print "Tomography macro"
	print ""
	print "USAGE"
	print "Input parameters"
	print "   $0 = scanType"
	print "   tomography-scan.py <scanType>"
	print ""
	print "ARGUMENTS"
	print "   scanType      Scan type"
	print "		 2 - Fast Scan Mode"
	print "	         5 - Fast Scan DPC Mode"
	print "		 6 - Snap&Snap Mode"
	print "	         7 - Snap&Step DPC Mode"
	sys.exit()

def standardChannelDefinition(operationMode):

	global chStorage,chFilePrefix, chUserID
	global chServer,chEndstation
	global chGo, chPause, chExperimentStatus, chCameraStatus
	global chScanInterruption, chComputeSinograms
	global chActualRotation, chScanTimeToGo
	global chRoi, chExposure, chRotyMin, chRotyMax, chRotationAxisPosition
	global chNumberOfDarks, chNumberOfFlats, chNumberOfProjections
	global chXLinIn, chXLinOut, chTriggerDelay
	
	if operationMode!=2:
		chStorage=epicsPV('X02DA-SCAN-CAM1:STORAGE')
		chFilePrefix=epicsPV('X02DA-SCAN-CAM1:FILPRE')
		chServer=epicsPV("X02DA-ES1-CAM1:SERV_SEL")
		chEndstation=epicsPV("X02DA-ES1-CAM1:ENDST_SEL")
		chGo=epicsPV("X02DA-SCAN-SCN1:GO")
		chPause=epicsPV("X02DA-SCAN-SCN1:PAUSE")
		chExperimentStatus=epicsPV("X02DA-SCAN-SCN1:STATUS")
		chCameraStatus=epicsPV("X02DA-SCAN-CAM1:STATUS")
		chScanInterruption=epicsPV("X02DA-SCAN-SCN1:INTR")
		chComputeSinograms=epicsPV("X02DA-SCAN-SCN1:SINO")
		chUserID=epicsPV("X02DA-SCAN-SCN1:USERID")
		chActualRotation=epicsPV("X02DA-SCAN-SCN1:ACTROT")
		chScanTimeToGo=epicsPV("X02DA-SCAN-SCN1:SCNFINTME")
		chRoi=epicsPV("X02DA-SCAN-CAM1:ROI")
		chExposure=epicsPV("X02DA-SCAN-CAM1:EXPTME")
		chRotyMin=epicsPV("X02DA-SCAN-SCN1:ROTSTA")
		chRotyMax=epicsPV("X02DA-SCAN-SCN1:ROTSTO")
		chRotationAxisPosition=epicsPV("X02DA-SCAN-SCN1:STITCH")
		chNumberOfDarks=epicsPV("X02DA-SCAN-SCN1:NPPDRK")
		chNumberOfFlats=epicsPV("X02DA-SCAN-SCN1:NPPFLT")
		chNumberOfProjections=epicsPV("X02DA-SCAN-SCN1:NPRJ")
		chXLinIn=epicsPV("X02DA-SCAN-SCN1:SMPIN")
		chXLinOut=epicsPV("X02DA-SCAN-SCN1:SMPOUT")
		chTriggerDelay=epicsPV("X02DA-SCAN-SCN1:TRIDEL")
	else:
		channelPrefix="X02DA-SOFTTEST-TEST"
		chStorage=epicsPV(channelPrefix+":STORAGE")
		chFilePrefix=epicsPV(channelPrefix+":FILPRE")
		chServer=epicsPV(channelPrefix+":SERV_SEL")
		chEndstation=epicsPV(channelPrefix+":ENDST_SEL")
		chGo=epicsPV(channelPrefix+":GO")
		chPause=epicsPV(channelPrefix+":PAUSE")
		chExperimentStatus=epicsPV(channelPrefix+":STATUS")
		chCameraStatus=epicsPV(channelPrefix+":STATUS")
		chScanInterruption=epicsPV(channelPrefix+":INTR")
		chComputeSinograms=epicsPV(channelPrefix+":SINO")
		chUserID=epicsPV(channelPrefix+":USERID")
		chActualRotation=epicsPV(channelPrefix+":ACTROT")
		chScanTimeToGo=epicsPV(channelPrefix+":SCNFINTME")
		chRoi=epicsPV(channelPrefix+":ROI")
		chExposure=epicsPV(channelPrefix+":EXPTME")
		chRotyMin=epicsPV(channelPrefix+":ROTSTA")
		chRotyMax=epicsPV(channelPrefix+":ROTSTO")
		chRotationAxisPosition=epicsPV(channelPrefix+":STITCH")
		chNumberOfDarks=epicsPV(channelPrefix+":NPPDRK")
		chNumberOfFlats=epicsPV(channelPrefix+":NPPFLT")
		chNumberOfProjections=epicsPV(channelPrefix+":NPRJ")
		chXLinIn=epicsPV(channelPrefix+":SMPIN")
		chXLinOut=epicsPV(channelPrefix+":SMPOUT")

	chGo.setMonitor()
	chPause.setMonitor()
		

def cameraChannelDefinition(beamline,server):

	global chCCDCAM_SET_PARAM
	global chCCDCAM_RECMODE       
	global chCCDCAM_STOREMODE     
	global chCCDCAM_DELAY         
	global chCCDCAM_FILENR        
	global chCCDCAM_SAVESTOP      
	global chCCDCAM_SAVESTART     
	global chCCDCAM_CLEARMEM      
	global chCCDCAM_STATUSCODE   
	global chCCDCAM_CAMERA        
	global chCCDCAM_COCTIME       
	global chCCDCAM_TRIGGER       
	global chCCDCAM_ACQMODE       
	global chCCDCAM_FILEFORMAT    
	global chCCDCAM_EXPOSURE      
	global chCCDCAM_FILESAVEBUSY  
	global chCCDCAM_CAMPROGRESS   
	global chCCDCAM_FTRANSFER     
	global chCCDCAM_FTRANSFERSEVR 
	global chCCDCAM_FILEPATH      
	global chCCDCAM_FILEPATHSEVR      
	global chCCDCAM_FILEPATHSTAT      
	global chCCDCAM_FILENAME      
	global chCCDCAM_REGIONX_START 
	global chCCDCAM_REGIONX_END   
	global chCCDCAM_REGIONY_START 
	global chCCDCAM_REGIONY_END
	global chCCDCAM_CCDTEMP       
	global chCCDCAM_HEIGHT        
	global chCCDCAM_WIDTH         
	global chCCDCAM_PIC_MAX       
	global chCCDCAM_PIC_BUFFER    
	global chCCDCAM_CAMRATE       
	global chCCDCAM_INIT          
	global chCCDCAM_HSSPEED       
	global chCCDCAM_TRANSFER     
	global chCCDCAM_FILERATE     
	global chCCDCAM_HWFILENR      
	global chCCDCAM_POWERTEMP     
	global chCCDCAM_ERRCODE       
	global chCCDCAM_WARNCODE      
	global chCCDCAM_CAMTEMP       
	global chCCDCAM_BUSY          
	
	chCCDCAM_SET_PARAM     = epicsPV(beamline+"-"+server+":SET_PARAM")
	chCCDCAM_RECMODE       = epicsPV(beamline+"-"+server+":RECMODE")
	chCCDCAM_STOREMODE     = epicsPV(beamline+"-"+server+":STOREMODE")
	chCCDCAM_DELAY         = epicsPV(beamline+"-"+server+":DELAY")
	chCCDCAM_FILENR        = epicsPV(beamline+"-"+server+":FILENR")
	chCCDCAM_SAVESTOP      = epicsPV(beamline+"-"+server+":SAVESTOP")
	chCCDCAM_SAVESTART     = epicsPV(beamline+"-"+server+":SAVESTART")
	chCCDCAM_CLEARMEM      = epicsPV(beamline+"-"+server+":CLEARMEM")
	chCCDCAM_CAMERA        = epicsPV(beamline+"-"+server+":CAMERA")
	chCCDCAM_COCTIME       = epicsPV(beamline+"-"+server+":COCTIME")
	chCCDCAM_TRIGGER       = epicsPV(beamline+"-"+server+":TRIGGER")
	chCCDCAM_ACQMODE       = epicsPV(beamline+"-"+server+":ACQMODE")
	chCCDCAM_FILEFORMAT    = epicsPV(beamline+"-"+server+":FILEFORMAT")
	chCCDCAM_EXPOSURE      = epicsPV(beamline+"-"+server+":EXPOSURE")
	#	chCCDCAM_FILESAVEBUSY  = epicsPV(beamline+"-"+server+":FILESAVEBUSY.RVAL")
	chCCDCAM_FILESAVEBUSY  = epicsPV(beamline+"-"+server+":FILESAVEBUSY")
	chCCDCAM_CAMPROGRESS   = epicsPV(beamline+"-"+server+":CAMPROGRESS")
	chCCDCAM_FTRANSFER     = epicsPV(beamline+"-"+server+":FTRANSFER")
	chCCDCAM_FTRANSFERSEVR = epicsPV(beamline+"-"+server+":FTRANSFER.SEVR")
	chCCDCAM_FILEPATH      = epicsPV(beamline+"-"+server+":FILEPATH")
	chCCDCAM_FILEPATHSEVR  = epicsPV(beamline+"-"+server+":FILEPATH.SEVR")
	chCCDCAM_FILEPATHSTAT  = epicsPV(beamline+"-"+server+":FILEPATH.STAT")
	chCCDCAM_FILENAME      = epicsPV(beamline+"-"+server+":FILENAME")
	chCCDCAM_REGIONX_START = epicsPV(beamline+"-"+server+":REGIONX_START")
	chCCDCAM_REGIONX_END   = epicsPV(beamline+"-"+server+":REGIONX_END")
	chCCDCAM_REGIONY_START = epicsPV(beamline+"-"+server+":REGIONY_START")
	chCCDCAM_REGIONY_END   = epicsPV(beamline+"-"+server+":REGIONY_END")
	
  # The following variables are not used for the moment but are listed for completeness

	chCCDCAM_STATUSCODE    = epicsPV(beamline+"-"+server+":STATUSCODE")
	chCCDCAM_CCDTEMP       = epicsPV(beamline+"-"+server+":CCDTEMP")
	chCCDCAM_HEIGHT        = epicsPV(beamline+"-"+server+":HEIGHT")
	chCCDCAM_WIDTH         = epicsPV(beamline+"-"+server+":WIDTH")
	chCCDCAM_PIC_MAX       = epicsPV(beamline+"-"+server+":PIC_MAX")
	chCCDCAM_PIC_BUFFER    = epicsPV(beamline+"-"+server+":PIC_BUFFER")
	chCCDCAM_CAMRATE       = epicsPV(beamline+"-"+server+":CAMRATE")
	chCCDCAM_INIT          = epicsPV(beamline+"-"+server+":INIT")
	chCCDCAM_HSSPEED       = epicsPV(beamline+"-"+server+":HSSPEED")
	chCCDCAM_TRANSFER      = epicsPV(beamline+"-"+server+":TRANSFER")
	chCCDCAM_FILERATE      = epicsPV(beamline+"-"+server+":FILERATE")
	chCCDCAM_HWFILENR      = epicsPV(beamline+"-"+server+":HWFILENR")
	chCCDCAM_POWERTEMP     = epicsPV(beamline+"-"+server+":POWERTEMP")
	chCCDCAM_ERRCODE       = epicsPV(beamline+"-"+server+":ERRCODE")
	chCCDCAM_WARNCODE      = epicsPV(beamline+"-"+server+":WARNCODE")
	chCCDCAM_CAMTEMP       = epicsPV(beamline+"-"+server+":CAMTEMP")
	chCCDCAM_BUSY          = epicsPV(beamline+"-"+server+":BUSY")
	
  # Set monitors
  	
	chCCDCAM_FILESAVEBUSY.setMonitor()
	chCCDCAM_CAMPROGRESS.setMonitor()	
	
def rotationStageDefinition(rotationStage,endstationPrefix,beamline):

	global chROT_SET_ABS, chROT_GET_POS, chROT_SVEL, chROT_GVEL, chROT_STOP, chROT_TWEAK, chROT_GACC 
	global chROT_SNAP_START, chROT_SNAP_OFFSET, chROT_DIRECT_MODE, chROT_STAB_TIME, chROT_REPETIONS
	global chROT_PULSE_WIDTH, chROT_COUNTER, chROT_SNAP_READY, chROT_START, chROT_MOVE
	global chSampleX, chSampleY, chSampleZ, chSampleXX, chSampleZZ, chMicroscopeX, chMicroscopeY, chMicroscopeZ
	
	if rotationStage!="Aerotech" and rotationStage!="Micos":
		print "The " + rotationStage + " rotation stage has not been implemented yet"
	

	chROT_SET_ABS         = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYUSETP")
	chROT_GET_POS         = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYUGETP")
	chROT_GET_POS.setMonitor()
	chROT_SVEL            = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYSETVE")
	chROT_MOVE            = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYASTAT")

	if rotationStage=="Aerotech":
		
		chROT_STOP        = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYESTOP.PROC")
		chROT_SNAP_START  = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYMSTART")
		chROT_SNAP_OFFSET = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYMOFFS")
		chROT_DIRECT_MODE = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTY-DMODE")
		chROT_STAB_TIME   = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYMTRIGDLY")
		chROT_TWEAK       = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYMDIST")
		chROT_REPETIONS   = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYMREP")
		chROT_PULSE_WIDTH = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:#ROTYPULSEON")
		chROT_COUNTER     = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYSCNT")
		chROT_SNAP_READY  = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTY-M2READY.PROC")
		chROT_START       = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTY-M2START.PROC")
		chROT_GVEL        = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYSETVE")
		chROT_GACC        = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYSETAC")
		
		chSampleX=epicsMotor("X02DA-ES1-SMP1:TRX")
		chSampleY=epicsPV("X02DA-ES1-SMP1:TRY-VAL")
		chSampleZ=epicsMotor("X02DA-ES1-SMP1:TRZ")
		chSampleXX=epicsMotor("X02DA-ES1-SMP1:TRXX")
		chSampleZZ=epicsMotor("X02DA-ES1-SMP1:TRZZ")
		chMicroscopeX=epicsMotor("X02DA-ES1-MS1:TRX")
		chMicroscopeY=epicsMotor("X02DA-ES1-MS1:TRY")
		chMicroscopeZ=epicsMotor("X02DA-ES1-MS1:TRZ")
		
	elif rotationStage=="Micos":

		chROT_STOP        = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYSTOP.PROC")
		chROT_TWEAK       = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYTWEAK")
		chROT_GVEL        = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYGETVE")
		chROT_GACC        = epicsPV(beamline+"-"+endstationPrefix+"-SMP1:ROTYGETAC")
		
		chSampleX=epicsMotor("X02DA-ES2-SMP1:TRX")
		chSampleY=epicsPV("X02DA-ES2-SMP1:TRY-VAL")
		chSampleZ=epicsMotor("X02DA-ES2-SMP1:TRZ")
		chSampleXX=epicsMotor("X02DA-ES2-SMP1:TRXX")
		chSampleZZ=epicsMotor("X02DA-ES2-SMP1:TRZZ")
		chMicroscopeX=epicsMotor("X02DA-ES2-DET1:TRX")
		chMicroscopeY=epicsMotor("X02DA-ES2-DET1:TRY")
		chMicroscopeZ=epicsMotor("X02DA-ES2-DET1:TRZ")

def moveRotationWait(value):

	poll=1
	
	chROT_SET_ABS.putWait(value)
	# To be sure that the rotation starts before I pull
	time.sleep(1)
	
	while (1):
		movementDone = chROT_MOVE.getw(req_type=ca.DBF_STRING)
		if movementDone!="MOVING" and movementDone!="1":
			break
		time.sleep(poll)
				
def checkpausestop_fast():

	global scanInterruption, logFile

	scanStatus=chGo.getw()
	
	if scanStatus!=1:

		FILE = open(logFile,"a")
		FILE.write("SCAN HAS BEEN INTERRUPTED!!!!!\n")
		FILE.close()
		print "SCAN HAS BEEN INTERRUPTED!!!!!"
		chCCDCAM_SAVESTOP.putWait(0)
		chCameraStatus.putWait(0)
		
		cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
		while cameraSaveBusy==1:
			cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
			time.sleep(0.5)
			
		chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
		chROT_STOP.putWait(0)
		
		scanInterruption=1
		chScanTimeToGo.putWait(0)
		
def checkpausestop_fast_dpc():

	global scanInterruption
	global scanPause
	global logFile

	# Abort scan if stop button is pressed!
	
	scanStatus=chGo.getw()
	
	if scanStatus!=1:
		FILE = open(logFile,"a")
		FILE.write("SCAN HAS BEEN INTERRUPTED!!!!!\n")
		FILE.close()
		print "SCAN HAS BEEN INTERRUPTED!!!!!"
		chCCDCAM_SAVESTOP.putWait(0)
		chCameraStatus.putWait(0)
		
		cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
		while cameraSaveBusy==1:
			cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
			time.sleep(0.5)
			
		chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
		chROT_STOP.putWait(0)
		
		scanInterruption=1
		return
	
	# Check if scan has been paused
	
	pauseStatus=chPause.getw()
	if pauseStatus!=0:
		FILE = open(logFile,"a")
		FILE.write("SCAN HAS BEEN PAUSED!!!!!\n")
		FILE.close()
		print "SCAN HAS BEEN PAUSED!!!"
		chCCDCAM_SAVESTOP.putWait(0)
		cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
		while cameraSaveBusy==1:
			cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
			time.sleep(0.5)

		chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
		chROT_STOP.putWait(0)
		scanPause=1
	
	while pauseStatus!=0 and scanStatus==1:
		time.sleep(0.1)
		pauseStatus=chPause.getw()
		scanStatus=chGo.getw()
				
def snap_fifo():

	global totalScanTime, logFile

	# Let perform some checks for beam status
	if operationMode==0:
		ringCurrentStatus=chRingCurrentStatus.getw()
		interlockStatus=chInterlockStatus.getw()
		absorberStatus=chAbsorberStatus.getw()
	else:
		ringCurrentStatus=chRingCurrentStartFake.getw()
		interlockStatus=0
		absorberStatus=1
	
	# Interrupt the scan if there is a beam dump, an optics interlock or the absorber has been closed
	
	if ringCurrentStatus <= ringCurrentStart-0.05*ringCurrentStart:
		FILE = open(logFile,"a")
		FILE.write("Scan is going to be interrupted because of a beam dump!\n")
		FILE.close()
		print "Scan is going to be interrupted because of a beam dump!"
		chGo.putWait(0)
	if interlockStatus==1:
		FILE = open(logFile,"a")
		FILE.write("Scan is going to be interrupted because of an optics interlock!\n")
		FILE.close()
		print "Scan is going to be interrupted because of an optics interlock!"
		chGo.putWait(0)
	if absorberStatus==0:
		FILE = open(logFile,"a")
		FILE.write("Scan is going to be interrupted because the absorber has been closed!\n")
		FILE.close()
		print "Scan is going to be interrupted because the absorber has been closed!"
		chGo.putWait(0)
	
	# Start the camera
	cameraStatus=chCCDCAM_CAMERA.getw(req_type=ca.DBF_STRING)
	if cameraStatus=="OFF":
		print "Starting the camera"
		chCCDCAM_CAMERA.putWait("RUNNING",req_type=ca.DBF_STRING)
		time.sleep(5)
	chCCDCAM_FTRANSFER.putWait(1)
	
	cameraProgress=chCCDCAM_CAMPROGRESS.getw()
	cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
	
	while cameraSaveBusy==1:
			 
		if operationMode==0:
			ringCurrentStatus=chRingCurrentStatus.getw()
			interlockStatus=chInterlockStatus.getw()
			absorberStatus=chAbsorberStatus.getw()
		else:
			ringCurrentStatus=chRingCurrentStartFake.getw()
			interlockStatus=0
			absorberStatus=1
	
		# Interrupt the scan if there is a beam dump, an optics interlock or the absorber has been closed
	
		if ringCurrentStatus <= ringCurrentStart-0.05*ringCurrentStart:
			FILE = open(logFile,"a")
			FILE.write("Scan is going to be interrupted because of a beam dump!\n")
			FILE.close()
			print "Scan is going to be interrupted because of a beam dump!"
			chGo.putWait(0)
		if interlockStatus==1:
			FILE = open(logFile,"a")
			FILE.write("Scan is going to be interrupted because of an optics interlock!\n")
			FILE.close()
			print "Scan is going to be interrupted because of an optics interlock!"
			chGo.putWait(0)
		if absorberStatus==0:
			FILE = open(logFile,"a")
			FILE.write("Scan is going to be interrupted because the absorber has been closed!\n")
			FILE.close()
			print "Scan is going to be interrupted because the absorber has been closed!"
			chGo.putWait(0)
			
		checkpausestop_fast()
		
		cameraProgress=chCCDCAM_CAMPROGRESS.getw()
		cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
		print "Acquiring projections ... %2.2f" % cameraProgress + "% ... done"
		
		if rotyMax!=rotyMin:
			currentAngle=chROT_GET_POS.getw()
			timeToGo=totalScanTime*(1-((currentAngle-rotyMin)/(rotyMax-rotyMin)))
			currentRotation=((currentAngle-rotyMin)/(rotyMax-rotyMin))
			if currentRotation>=0:
				chActualRotation.putWait(currentRotation)
			else:
				chActualRotation.putWait(0)			
			if math.fabs(currentAngle-rotyMin)>1e-4:
				chScanTimeToGo.putWait(timeToGo)
		
		time.sleep(2)
		
	chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
	chCameraStatus.putWait("Idle")

def snap_dpc():

	global scanPause
	global totalScanTime
	global NSteps, iPhase
	
	beamDump=0
	# Let perform some checks for beam status
	if operationMode==0:
		ringCurrentStatus=chRingCurrentStatus.getw()
		interlockStatus=chInterlockStatus.getw()
		absorberStatus=chAbsorberStatus.getw()
	else:
		ringCurrentStatus=chRingCurrentStartFake.getw()
		interlockStatus=0
		absorberStatus=1
	
	# Check for a beam dump, an optics interlock or a closed absorber
	
	scanStatus=chGo.getw()
	
	while (ringCurrentStatus <= ringCurrentStart-0.05*ringCurrentStart or interlockStatus==1 or absorberStatus==0) and scanStatus==1:
	
		if scanPause!=1:
			scanPause=1
			chPause.putWait(1)

			chCCDCAM_SAVESTOP.putWait(0)
			cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
			while cameraSaveBusy==1:
				cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
				time.sleep(0.5)

			chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
			chROT_STOP.putWait(0)
		
		if operationMode==0:
			ringCurrentStatus=chRingCurrentStatus.getw()
			interlockStatus=chInterlockStatus.getw()
			absorberStatus=chAbsorberStatus.getw()
		else:
			ringCurrentStatus=chRingCurrentStartFake.getw()
			interlockStatus=0
			absorberStatus=1
		
		beamDump=1
		scanStatus=chGo.getw()		
		
	
		if ringCurrentStatus >= ringCurrentStart-0.05*ringCurrentStart and interlockStatus==0 and absorberStatus==0:
		
			FILE = open(logFile,"a")
			FILE.write("The absorber has been closed by the interlock!!!\n")
			FILE.close()
			print "The absorber has been closed by the interlock!!!"
			chAbsorberStatus.putWait(1)
			FILE = open(logFile,"a")
			FILE.write("Waiting for 10s for thermal compenstaion after the absorber has been opened ...\n")
			FILE.close()
			print "Waiting for 10s for thermal compenstaion after the absorber has been opened ..."
			time.sleep(10)
	
	if beamDump==1:
		chPause.putWait(0)
		beamDump=0
	
	checkpausestop_fast_dpc()
	
	if scanPause!=1:
		
		# Start the camera
		cameraStatus=chCCDCAM_CAMERA.getw(req_type=ca.DBF_STRING)
		if cameraStatus=="OFF":
			print "Starting the camera"
			chCCDCAM_CAMERA.putWait("RUNNING",req_type=ca.DBF_STRING)
		chCCDCAM_FTRANSFER.putWait(1)
	
		cameraProgress=chCCDCAM_CAMPROGRESS.getw()
		cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
	
		while cameraSaveBusy==1:
			 
			if operationMode==0:
				ringCurrentStatus=chRingCurrentStatus.getw()
				interlockStatus=chInterlockStatus.getw()
				absorberStatus=chAbsorberStatus.getw()
			else:
				ringCurrentStatus=chRingCurrentStartFake.getw()
				interlockStatus=0
				absorberStatus=1
	
			# Check for a beam dump, an optics interlock or a closed absorber
	
			scanStatus=chGo.getw()
	
			while (ringCurrentStatus <= ringCurrentStart-0.05*ringCurrentStart or interlockStatus==1 or absorberStatus==0) and scanStatus==1:
	
				if scanPause!=1:
					scanPause=1
					chPause.putWait(1)
					chCCDCAM_SAVESTOP.putWait(0)
					cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
					while cameraSaveBusy==1:
						cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
						time.sleep(0.5)

					chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
					chROT_STOP.putWait(0)
		
				if operationMode==0:
					ringCurrentStatus=chRingCurrentStatus.getw()
					interlockStatus=chInterlockStatus.getw()
					absorberStatus=chAbsorberStatus.getw()
				else:
					ringCurrentStatus=chRingCurrentStartFake.getw()
					interlockStatus=0
					absorberStatus=1
				
				beamDump=1
				scanStatus=chGo.getw()		
		
	
				if ringCurrentStatus >= ringCurrentStart-0.05*ringCurrentStart and interlockStatus==0 and absorberStatus==0:
		
					FILE = open(logFile,"a")
					FILE.write("The absorber has been closed by the interlock!!!\n")
					FILE.close()
					print "The absorber has been closed by the interlock!!!"
					chAbsorberStatus.putWait(1)
					FILE = open(logFile,"a")
					FILE.write("Waiting for 10s for thermal compenstaion after the absorber has been opened ...\n")
					FILE.close()
					print "Waiting for 10s for thermal compenstaion after the absorber has been opened ..."
					time.sleep(10)
	
			if beamDump==1:
				chPause.putWait(0)
				beamDump=0
	
			checkpausestop_fast_dpc()
		
			cameraProgress=chCCDCAM_CAMPROGRESS.getw()
			cameraSaveBusy=chCCDCAM_FILESAVEBUSY.getw()
			print "Acquiring projections ... %2.2f" % cameraProgress + "% ... done"
		
			if rotyMax!=rotyMin:
				currentAngle=chROT_GET_POS.getw()
				timeToGo=totalScanTime*(1-((currentAngle-rotyMin)/(rotyMax-rotyMin)))+totalScanTime*(NSteps-iPhase-1)
				chScanTimeToGo.putWait(timeToGo)
		
			time.sleep(2)
		
		chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
		chCameraStatus.putWait("Idle")

def fasttomoscan(rotyMin,rotyMax,numberOfProjections,exposure,xLinIn,xLinOut,numberOfDarks,numberOfFlats,crystal1Pitch,scanType,millisecondShutter,rotationStage):
	
	global scanInterruption
	global totalScanTime
	global logFile,sampleTifPath,logPath,databaseFile
	
	scanInterruption=0
	
	# Set the scan status flag to running
	chExperimentStatus.putWait("Running")
	print "TOMOGRAPHIC SCAN STARTED!!!"
	FILE = open(logFile,"a")
	FILE.write("TOMOGRAPHIC SCAN STARTED!!!\n")
	FILE.close()
	
	# Set scan type to continuous mode (just in case)
	if rotationStage=="Micos":
		chScanType.putWait(0)
	
	# Setting file format
	chCCDCAM_FILEFORMAT.putWait("TIFF")
	
	baseRotySpeed=chROT_GVEL.getw()
	
	# Select FIFO mode
	chCCDCAM_STOREMODE.putWait("FIFO Buffer")
	print "Fifo mode ON"
	chCCDCAM_RECMODE.putWait("Sequence")
	chCCDCAM_ACQMODE.putWait("Auto")
	chCCDCAM_TRIGGER.putWait("auto trigger")
	if scanType=="6":
		chCCDCAM_DELAY.putWait(0)
	chCCDCAM_SET_PARAM.putWait("SET")
	
	# This is to make the camera run with the correct settings
	# TODO do I need this??? Maybe for the COCTIME???
	#chCCDCAM_CLEARMEM.putWait("CLEAR")
	#chCCDCAM_CAMERA.putWait("RUNNING",req_type=ca.DBF_STRING)
	#time.sleep(1)
	#chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
	chCCDCAM_CLEARMEM.putWait("CLEAR")
	
	ccdFrameTime=chCCDCAM_COCTIME.getw()

	# Angular increment
	deltaRot=rotyMax-rotyMin
	if numberOfProjections!=0:
		angularIncrement=deltaRot/(numberOfProjections-1)
	else:
		angularIncrement=0
		
	if scanType=="6":
		chROT_TWEAK.putWait(angularIncrement)   
		if rotationStage=="Micos":
			systemOffset=chSystemOffset.getw()
			systemTime=systemOffset+(rotyMax-rotyMin)*1000/((numberOfProjections-1)*baseRotySpeed)
			systemTimeForFlats=systemOffset
			delay=systemTime+exposure-ccdFrameTime
			delayForFlats=systemTimeForFlats+exposure-ccdFrameTime
			totalScanTime=numberOfProjections*(exposure+systemTime)/1000
		else:
			stabilizationTime=chROT_STAB_TIME.getw()
			print "Stabilization time " + str(stabilizationTime) + " ms"
			totalScanTime=numberOfProjections*(ccdFrameTime+stabilizationTime)/1000
	elif scanType=="2":
		totalScanTime=numberOfProjections*ccdFrameTime/1000
	else:
		print "This scan type has not been implemented yet!"
		sys.exit()
		
	print "Total scan time " + str(totalScanTime) + " s"
		
	if deltaRot!=0 and scanType=="2":
		rotySpeed=deltaRot/((numberOfProjections-1)*ccdFrameTime)*1000
	else:
		rotySpeed=baseRotySpeed
		
	rotationAcceleration=chROT_GACC.getw()
	print "Acceleration " + str(rotationAcceleration)
	accelerationAngle=rotySpeed*rotySpeed/rotationAcceleration
	waitingTime=math.fabs(rotySpeed)/rotationAcceleration
	if waitingTime <= 0.2999:
		waitingTime=0.3
	
	if deltaRot!=0:
		if scanType=="2":
			rotationStart=rotyMin-rotySpeed*waitingTime-accelerationAngle
			rotationStop=rotationStart+deltaRot+2*(rotySpeed*waitingTime+accelerationAngle)
		elif scanType=="6":
			rotationStart=rotyMin-angularIncrement
			rotationStop=rotyMax
		else:
			print "This scan type has not been implemented yet!"
			sys.exit()
		
	else:
		rotationStart=rotyMin
		rotationStop=rotyMax
		
	print "Expected frame time " + str(ccdFrameTime) + " ms"
	print "Angular scan: " + str(deltaRot) + " degrees"
	print "Rotation speed (angle/s): " + str(math.fabs(rotySpeed))
	print "Base rotation speed (angle/s): " + str(baseRotySpeed)
	print "Start position: " + str(rotationStart)
	print "Acceleration angle: " + str(accelerationAngle)
	print "End position: " + str(rotationStop)
	
	if numberOfDarks>0:
		######################  Acquire  dark images   #################################
	
		print "\033[1m"  ## bold
		print "Acquiring dark images"
		print "\033[0m"	 ## back to normal
	
		print "Move to start position"
		print "Move rotation axis to: " + str(rotationStart)
		chROT_SVEL.putWait(baseRotySpeed)
		moveRotationWait(rotationStart)
	
		# Closing filter for dark acquisition
		if operationMode!=2:
			if crystal1Pitch>-100:
				print "Dump the beam by moving OP-FILTER 4 at -22.0 mm ..."
				chOPFilter4.move(-22)
			else:
				print "Dump the beam by moving OP-FILTER 4 at -12.0 mm ..."
				chOPFilter4.move(-12)
			chOPFilter4.wait(poll=1)
		else:
			if crystal1Pitch>-100:
				print "Dump the beam by moving OP-FILTER 4 at -22.0 mm ..."
			else:
				print "Dump the beam by moving OP-FILTER 4 at -12.0 mm ..."
	
		print "Wait for afterglow ..."
		print "Done!"
	
		# Set the channel of the tomography panel
		chCameraStatus.putWait("Acquiring")
	
		# Clear buffer
		chCCDCAM_CLEARMEM.putWait("CLEAR")
	
		print "Saving dark images 1-" + str(int(numberOfDarks))
		chCCDCAM_FILENR.putWait(1)
		chCCDCAM_SAVESTART.putWait(1)
		chCCDCAM_SAVESTOP.putWait(int(numberOfDarks))
	
		# Triggering the CCD acquisition sequence
		print "Send trigger to the camera"
		snap_fifo()
	
		chCameraStatus.putWait("Idle")
		print "Darks acquisition done!"
	
	if numberOfFlats>0:
		#################### Acquire pre flats  ########################################
	
		if scanInterruption==0:	

			print "\033[1m"  ## bold
			print "Acquiring pre-flat images"
			print "\033[0m"	 ## back to normal

			print "Moving the sample out of beam ..."
			chSampleX.move(xLinOut)
			chSampleX.wait(poll=1)	
	
			# Opening the shutter
			if operationMode!=2:
				chOPFilter4.move(0);chOPFilter4.wait(poll=1)
			print "Moving up the filter OP-FILTER 4 at 0.0 mm ..."
			time.sleep(3)

			moveRotationWait(rotationStart)
								
			if scanType=="6":
				if millisecondShutter=="Cam-Ctrl":
					if rotationStage=="Micos":
						chCCDCAM_DELAY.putWait(delayForFlats)
					else:
						chCCDCAM_DELAY.putWait(stabilizationTime)
					chCCDCAM_SET_PARAM.putWait("SET")
				
			# Set the channel of the tomography panel
			chCameraStatus.putWait("Acquiring")
	
			# Clear buffer
			chCCDCAM_CLEARMEM.putWait("CLEAR")

			print "Saving pre flats images " + str(int(numberOfDarks+1)) + "-" + str(int(numberOfDarks+numberOfFlats))
			chCCDCAM_FILENR.putWait(numberOfDarks+1)
			chCCDCAM_SAVESTART.putWait(1)
			chCCDCAM_SAVESTOP.putWait(numberOfFlats)
	
			# Triggering the CCD acquisition sequence
			print "Send trigger to the camera"
			snap_fifo()
	
			chCameraStatus.putWait("Idle")
			print "Pre flats acquisition done!"
				
			if scanType=="6":
				if millisecondShutter=="Cam-Ctrl":
					chCCDCAM_DELAY.putWait(0)
					chCCDCAM_SET_PARAM.putWait("SET")
						
	##################  Acquire projection images  ########################################
	
	if scanInterruption==0:
				 	
		print "\033[1m"  ## bold
		print "Acquiring projections"
		print "\033[0m"	 ## back to normal
	
		if numberOfFlats==0:
		
			if operationMode!=2:
				# Opening the shutter
				chOPFilter4.move(0);chOPFilter4.wait(poll=1)
			print "Moving up the filter OP-FILTER 4 at 0.0 mm ..."
			time.sleep(3)
			
		print "Saving projection images " + str(int(numberOfDarks+numberOfFlats+1)) + "-" + str(int(numberOfDarks+numberOfFlats+numberOfProjections))
		chCCDCAM_FILENR.putWait(numberOfDarks+numberOfFlats+1)
		chCCDCAM_SAVESTART.putWait(1)
		chCCDCAM_SAVESTOP.putWait(numberOfProjections)
				
		print "Moving the sample in the beam ..."
		chSampleX.move(xLinIn);chSampleX.wait(poll=1)
				
		if scanType=="2":
			print "Set the speed to: " + str(math.fabs(rotySpeed))
			if rotationStage=="Aerotech":
				chROT_STOP.putWait(0)
			chROT_SVEL.putWait(math.fabs(rotySpeed))
					
		# Clear buffer
		chCCDCAM_CLEARMEM.putWait("CLEAR")

		if scanType=="6":
			if rotationStage=="Micos":
				chScanType.putWait(1)
				chCCDCAM_DELAY.putWait(delay)
				chCCDCAM_SET_PARAM.putWait("SET")
			else:
				chBoxModeSelection.putWait("Snap\'n\'Step")
				chROT_GACC.putWait(500)
				chROT_TWEAK.putWait(angularIncrement)
				chROT_SNAP_START.putWait(rotationStart)
	   			chROT_REPETIONS.putWait(numberOfProjections)
				chROT_PULSE_WIDTH.putWait(1000)
				chROT_SNAP_READY.putWait(1)
				chROT_COUNTER.putWait(0)
				chCCDCAM_TRIGGER.putWait("ext.exp sfttrg")
				chCCDCAM_SET_PARAM.putWait("SET")
				time.sleep(1)
				chCCDCAM_CAMERA.putWait("RUNNING")
						
		# Set the channel of the tomography panel
		chCameraStatus.putWait("Acquiring")
					
		print "Rotation starts"
		if scanType=="2":
			chROT_SET_ABS.putWait(rotationStop)
		else:
			if rotationStage=="Aerotech":
				chROT_START.putWait(1)
				
		print "Send trigger to the camera"
		snap_fifo()
				
		chCameraStatus.putWait("Idle")
				
		if scanType=="6" and rotationStage=="Aerotech":
		
			chBoxModeSelection.putWait("Custom")
			chROT_GACC.putWait(rotationAcceleration)
			chROT_DIRECT_MODE.putWait(1)
			chCCDCAM_TRIGGER.putWait("auto trigger")
			chCCDCAM_SET_PARAM.putWait("SET")
					
		if scanInterruption==0:
			print "Projection acquisition done!"
			
	if numberOfFlats>0:
		#####################  Acquire post flats  #############################################
	
		if scanInterruption==0:
			 	
			chROT_STOP.putWait(0)
			chROT_SVEL.putWait(baseRotySpeed)
	
			if rotationStage=="Micos":
				chScanType.putWait(0)			
			print "Move Rotation to " + str(rotyMin)
			moveRotationWait(rotyMin)
			
			print "\033[1m"  ## bold
			print "Acquiring post-flat images"
			print "\033[0m"	 ## back to normal
						
			print "Moving the sample out of beam ..."
			chSampleX.move(xLinOut)
			chSampleX.wait(poll=1)
			
			if scanType=="6":
				if rotationStage=="Micos":
					chScanType.putWait(0)
					chCCDCAM_DELAY.putWait(delayForFlats)
				else:
					if millisecondShutter=="Cam-Ctrl":
						chCCDCAM_DELAY.putWait(stabilizationTime)
				chCCDCAM_SET_PARAM.putWait("SET")
			
			print "Saving post flat images " + str(int(numberOfDarks+numberOfFlats+numberOfProjections+1)) + "-" + str(int(numberOfDarks+2*numberOfFlats+numberOfProjections))
			chCCDCAM_FILENR.putWait(numberOfDarks+numberOfFlats+numberOfProjections+1)
			chCCDCAM_SAVESTART.putWait(1)
			chCCDCAM_SAVESTOP.putWait(numberOfFlats)

			# Clear buffer
			chCCDCAM_CLEARMEM.putWait("CLEAR")
				
			# Set the channel of the tomography panel
			chCameraStatus.putWait("Acquiring")
	
			print "Send trigger to the camera"
			snap_fifo()

			chCameraStatus.putWait("Idle")
			print "Post flats acquisition done!"
				
			if scanType=="6":
				if millisecondShutter=="Cam-Ctrl":
					chCCDCAM_DELAY.putWait(0)
					chCCDCAM_SET_PARAM.putWait("SET")
			
	print "Moving back to initial conditions ..."

	if scanInterruption==0:
		chComputeSinograms.putWait(1)

	# Close the shutter and put sample back!
	
	if operationMode!=2:
		if crystal1Pitch>-100:
			print "Dump the beam by moving OP_FILTER 4 to -22.0 mm ..."
			chOPFilter4.move(-22);chOPFilter4.wait(poll=1)
		else:
			print "Dump the beam by moving OP_FILTER 4 to -12.0 mm ..."
			chOPFilter4.move(-12);chOPFilter4.wait(poll=1)
	else:
		if crystal1Pitch>-100:
			print "Dump the beam by moving OP_FILTER 4 to -22.0 mm ..."
		else:
			print "Dump the beam by moving OP_FILTER 4 to -12.0 mm ..."
		
				
	print "Set rotation speed back to " + str(baseRotySpeed)
	#if rotationStage=="Aerotech":
	chROT_STOP.putWait(0)
	chROT_SVEL.putWait(baseRotySpeed)
	
	if rotationStage=="Micos":
		chScanType.putWait(0)			
	print "Move Rotation to " + str(rotyMin)
	moveRotationWait(rotyMin)
	if numberOfFlats>0:
		print "Moving the sample out of beam ..."
		chSampleX.move(xLinOut);chSampleX.wait(poll=1)
	
	chScanTimeToGo.putWait(0)
	
	if scanType=="6" and rotationStage=="Aerotech":
		chBoxModeSelection.putWait("Custom")
		chROT_GACC.putWait(rotationAcceleration)
		chROT_DIRECT_MODE.putWait(1)
		chCCDCAM_TRIGGER.putWait("auto trigger")
		chROT_COUNTER.putWait(0)

	FILE = open(logFile,"a")	
	FILE.write("TOMOGRAPHIC SCAN FINISHED at " + str(time.asctime(time.localtime(time.time())))+"\n")
	FILE.close()
	
	# Logging
	tree = ET.parse(databaseFile)
	sample = tree.getroot()
	scan = sample.find("./pointOfInterest/scan")
	endDate=ET.Element("endDate")
	endDate.text=str(time.asctime(time.localtime(time.time()))) 
	scan.append(endDate)
	tree.write(databaseFile)

	command = "cp " + logFile + " " + sampleTifPath
	os.system(command)
	command = "ln " + sampleTifPath + "/" + filePrefix + ".log " + logPath
	os.system(command)
	command = "rm " + logFile
	os.system(command)
	
	if scanInterruption==0:
		command = "curl -X PUT -H \"Content-Type: application/xml\" -d @\"" + databaseFile + "\" http://x02da-www-1:8080/ch.psi.epms.web/rs/epms/upload"
		os.system(command)
		command = "cp " + databaseFile + " " + sampleTifPath
		os.system(command)
		command = "ln " + sampleTifPath + "/" + filePrefix + ".xml " + logPath
		os.system(command)
		command = "rm " + databaseFile
		os.system(command)
	else:
		chScanInterruption.putWait(1)
	
	print "Set STOREMODE and RECMODE back to Recorder and Ring Buffer (for preview purposes)"
	chCCDCAM_STOREMODE.putWait("Recorder")
	chCCDCAM_RECMODE.putWait("Ring Buffer")
	chCCDCAM_SET_PARAM.putWait("SET")
	print "Fifo mode OFF"
	
	# Set the scan status flag to Idle
	chExperimentStatus.putWait("Idle")

def fastdpcscan(rotyMin,rotyMax,numberOfProjections,exposure,xLinIn,xLinOut,numberOfDarks,numberOfFlats,gridStart,gridEnd,gridNSteps,crystal1Pitch,scanType,millisecondShutter,rotationStage):
	
	global scanPause
	global scanInterruption
	global totalScanTime
	global NSteps, iPhase
	global logFile,sampleTifPath,logPath,databaseFile
	
	scanInterruption=0
	scanPause=0
	
	# Set the scan status flag to running
	chExperimentStatus.putWait("Running")
	print "DPC-TOMOGRAPHIC SCAN STARTED!!!"
	FILE = open(logFile,"a")
	FILE.write("DPC-TOMOGRAPHIC SCAN STARTED!!!\n")
	FILE.close()
	
	# Set scan type to continuous mode (just in case)
	if rotationStage=="Micos":
		chScanType.putWait(0)
	
	# Setting file format
	chCCDCAM_FILEFORMAT.putWait("TIFF")
	
	baseRotySpeed=chROT_GVEL.getw()
	
	# Select FIFO mode
	chCCDCAM_STOREMODE.putWait("FIFO Buffer")
	print "Fifo mode ON"
	chCCDCAM_RECMODE.putWait("Sequence")
	chCCDCAM_ACQMODE.putWait("Auto")
	chCCDCAM_TRIGGER.putWait("auto trigger")
	if scanType=="7":
		chCCDCAM_DELAY.putWait(0)
	chCCDCAM_SET_PARAM.putWait("SET")
	
	# This is to make the camera run with the correct settings
	# TODO do I need this??? Maybe for the COCTIME???
	#chCCDCAM_CLEARMEM.putWait("CLEAR")
	#chCCDCAM_CAMERA.putWait("RUNNING",req_type=ca.DBF_STRING)
	#time.sleep(1)
	#chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
	chCCDCAM_CLEARMEM.putWait("CLEAR")
	
	# Grid increment
	gridStepSize=(gridEnd-gridStart)/gridNSteps
	NSteps=gridNSteps+1

	# Total number of projections
	totalNumberOfProjections=numberOfDarks+numberOfFlats*2*NSteps+numberOfProjections*NSteps
	
	ccdFrameTime=chCCDCAM_COCTIME.getw()

	# Angular increment
	deltaRot=rotyMax-rotyMin
	if numberOfProjections!=0:
		angularIncrement=deltaRot/(numberOfProjections-1)
	else:
		angularIncrement=0
		
	if scanType=="7":
		chROT_TWEAK.putWait(angularIncrement)   
		if rotationStage=="Micos":
			systemOffset=chSystemOffset.getw()
			systemTime=systemOffset+(rotyMax-rotyMin)*1000/((numberOfProjections-1)*baseRotySpeed)
			systemTimeForFlats=systemOffset
			delay=systemTime+exposure-ccdFrameTime
			delayForFlats=systemTimeForFlats+exposure-ccdFrameTime
			totalScanTime=numberOfProjections*(exposure+systemTime)/1000
		else:
			stabilizationTime=chROT_STAB_TIME.getw()
			print "Stabilization time " + str(stabilizationTime) + " ms"
			totalScanTime=numberOfProjections*(ccdFrameTime+stabilizationTime)/1000
	elif scanType=="5":
		totalScanTime=numberOfProjections*ccdFrameTime/1000
	else:
		print "This scan type has not been implemented yet!"
		sys.exit()
		
	if deltaRot!=0 and scanType=="5":
		rotySpeed=deltaRot/((numberOfProjections-1)*ccdFrameTime)*1000
	else:
		rotySpeed=baseRotySpeed
		
	rotationAcceleration=chROT_GACC.getw()
	print "Acceleration " + str(rotationAcceleration)
	accelerationAngle=rotySpeed*rotySpeed/rotationAcceleration
	waitingTime=math.fabs(rotySpeed)/rotationAcceleration
	if waitingTime <= 0.2999:
		waitingTime=0.3
	
	if deltaRot!=0:
		if scanType=="5":
			rotationStart=rotyMin-rotySpeed*waitingTime-accelerationAngle
			rotationStop=rotationStart+deltaRot+2*(rotySpeed*waitingTime+accelerationAngle)
		elif scanType=="7":
			rotationStart=rotyMin-angularIncrement
			rotationStop=rotyMax
		else:
			print "This scan type has not been implemented yet!"
			sys.exit()
		
	else:
		rotationStart=rotyMin
		rotationStop=rotationStart
		
	print "Expected frame time " + str(ccdFrameTime) + " ms"
	print "Angular scan: " + str(deltaRot) + " degrees"
	print "Rotation speed (angle/s): " + str(math.fabs(rotySpeed))
	print "Base rotation speed (angle/s): " + str(baseRotySpeed)
	print "Start position: " + str(rotationStart)
	print "Acceleration angle: " + str(accelerationAngle)
	print "End position: " + str(rotationStop)
	
	
	######################  Acquire  dark images   #################################
	
	print "\033[1m"  ## bold
	print "Acquiring dark images"
	print "\033[0m"	 ## back to normal
	
	print "Move to start position"
	print "Move rotation axis to: " + str(rotationStart)
	chROT_SVEL.putWait(baseRotySpeed)
	moveRotationWait(rotationStart)
	
	# Closing filter for dark acquisition
	if operationMode!=2:
		if crystal1Pitch>-100:
			print "Dump the beam by moving OP-FILTER 4 at -22.0 mm ..."
			chOPFilter4.move(-22)
		else:
			print "Dump the beam by moving OP-FILTER 4 at -12.0 mm ..."
			chOPFilter4.move(-12)
		chOPFilter4.wait(poll=1)
	else:
		if crystal1Pitch>-100:
			print "Dump the beam by moving OP-FILTER 4 at -22.0 mm ..."
		else:
			print "Dump the beam by moving OP-FILTER 4 at -12.0 mm ..."
	
	print "Wait for afterglow ..."
	time.sleep(5)
	print "Done!"
	
	# Set the channel of the tomography panel
	chCameraStatus.putWait("Acquiring")
	
	# Clear buffer
	chCCDCAM_CLEARMEM.putWait("CLEAR")
	
	print "Saving dark images 1-" + str(int(numberOfDarks))
	chCCDCAM_FILENR.putWait(1)
	chCCDCAM_SAVESTART.putWait(1)
	chCCDCAM_SAVESTOP.putWait(int(numberOfDarks))
	
	# Triggering the CCD acquisition sequence
	print "Send trigger to the camera"
	snap_fifo()
	
	chCameraStatus.putWait("Idle")
	print "Darks acquisition done!"
	
	print "Moving the sample out of beam ..."
	chSampleX.move(xLinOut)
	chSampleX.wait(poll=1)
	
	##################### Start step scans  #######################################
	
	print "\033[1m"  ## bold
	print "Starting grating stepping"
	print "\033[0m"	 ## back to normal
	
	# Opening the shutter
	print "Moving up the filter OP-FILTER 4 at 0.0 mm ..."
	if operationMode!=2:
		chOPFilter4.move(0);chOPFilter4.wait(poll=1)
	time.sleep(3)

	# Defining a loop to take a block of flats and a tomograph for each grating step
	
	iPhase=0
	while iPhase<int(NSteps):
		chActualStep.putWait(iPhase+1)
		pauseFound=0
		
	#################### Acquire pre flats  ########################################
		
		if scanInterruption==0:
			if scanPause==1:
				if pauseFound==0:
					pauseFound=1
					iPhase=iPhase-1
			else:
				 	
				print "\033[1m"  ## bold
				print "Grating step " + str(iPhase+1)
				print "\033[0m"	 ## back to normal
				
				FILE = open(logFile,"a")
				FILE.write("Grating step " + str(iPhase+1) + "\n")
				FILE.close()
				
				gratingPosition=gridStart+iPhase*gridStepSize
				print "Move grating to " + str(gratingPosition)
				
				if operationMode==0:
					chPiezo.move(gratingPosition)
					chPiezo.wait(poll=1)

				moveRotationWait(rotationStart)
				
				print "\033[1m"  ## bold
				print "Acquiring pre flats " + str(iPhase+1)
				print "\033[0m"	 ## back to normal
				
				if scanType=="7":
					if millisecondShutter=="Cam-Ctrl":
						if rotationStage=="Micos":
							chCCDCAM_DELAY.putWait(delayForFlats)
						else:
							chCCDCAM_DELAY.putWait(stabilizationTime)
						chCCDCAM_SET_PARAM.putWait("SET")					
				
				# Set the channel of the tomography panel
				chCameraStatus.putWait("Acquiring")
	
				# Clear buffer
				chCCDCAM_CLEARMEM.putWait("CLEAR")

				print "Saving pre flats images " + str(int(numberOfDarks+iPhase*(2*numberOfFlats+numberOfProjections)+1)) + "-" + str(int(numberOfDarks+iPhase*(2*numberOfFlats+numberOfProjections)+numberOfFlats))
				chCCDCAM_FILENR.putWait(numberOfDarks+iPhase*(2*numberOfFlats+numberOfProjections)+1)
				chCCDCAM_SAVESTART.putWait(1)
				chCCDCAM_SAVESTOP.putWait(numberOfFlats)
	
				# Triggering the CCD acquisition sequence
				print "Send trigger to the camera"
				snap_dpc()
	
				chCameraStatus.putWait("Idle")
				print "Pre flats acquisition done!"
				
				if scanType=="7":
					if millisecondShutter=="Cam-Ctrl":
						chCCDCAM_DELAY.putWait(0)
						chCCDCAM_SET_PARAM.putWait("SET")
						
	##################  Acquire projection images  ########################################
	
		if scanInterruption==0:
			if scanPause==1:
				if pauseFound==0:
					pauseFound=1
					iPhase=iPhase-1
			else:
				 	
				print "\033[1m"  ## bold
				print "Acquiring projections " + str(iPhase+1)
				print "\033[0m"	 ## back to normal
		
				print "Saving projection images " + str(int(numberOfDarks+iPhase*(2*numberOfFlats+numberOfProjections)+numberOfFlats+1)) + "-" + str(int(numberOfDarks+iPhase*(2*numberOfFlats+numberOfProjections)+numberOfFlats+numberOfProjections))
				chCCDCAM_FILENR.putWait(numberOfDarks+iPhase*(2*numberOfFlats+numberOfProjections)+numberOfFlats+1)
				chCCDCAM_SAVESTART.putWait(1)
				chCCDCAM_SAVESTOP.putWait(numberOfProjections)
				
				print "Moving the sample in the beam ..."
				chSampleX.move(xLinIn);chSampleX.wait(poll=1)
				
				if scanType=="5":
					print "Set the speed to: " + str(math.fabs(rotySpeed))
					if rotationStage=="Aerotech":
						chROT_STOP.putWait(0)
					chROT_SVEL.putWait(math.fabs(rotySpeed))
					
				if scanType=="7":
					if rotationStage=="Micos":
						chScanType.putWait(1)
						chCCDCAM_DELAY.putWait(delay)
						chCCDCAM_SET_PARAM.putWait("SET")
					else:
						chBoxModeSelection.putWait("Snap\'n\'Step")
						chROT_GACC.putWait(500)
						chROT_TWEAK.putWait(angularIncrement)
						chROT_SNAP_START.putWait(rotationStart)
	   					chROT_REPETIONS.putWait(numberOfProjections)
						chROT_PULSE_WIDTH.putWait(1000)
						chROT_SNAP_READY.putWait(1)
						chROT_COUNTER.putWait(0)
						chCCDCAM_TRIGGER.putWait("ext.exp sfttrg")
						chCCDCAM_SET_PARAM.putWait("SET")
						time.sleep(1)
						chCCDCAM_CAMERA.putWait("RUNNING")

				# Set the channel of the tomography panel
				chCameraStatus.putWait("Acquiring")
	
				# Clear buffer
				chCCDCAM_CLEARMEM.putWait("CLEAR")
				
				print "Rotation starts"
				if scanType=="5":
					chROT_SET_ABS.putWait(rotationStop)
				else:
					if rotationStage=="Aerotech":
						chROT_START.putWait(1)
					
				print "Send trigger to the camera"
				snap_dpc()
				
				chCameraStatus.putWait("Idle")

				if scanType=="7" and rotationStage=="Aerotech":
		
					chBoxModeSelection.putWait("Custom")
					chROT_GACC.putWait(rotationAcceleration)
					chROT_DIRECT_MODE.putWait(1)
					chCCDCAM_TRIGGER.putWait("auto trigger")
					chCCDCAM_SET_PARAM.putWait("SET")

				if scanInterruption==0:
					print "Projection acquisition done!"
				
	#####################  Acquire post flats  #############################################
	
		if scanInterruption==0:
			if scanPause==1:
				if pauseFound==0:
					pauseFound=1
					iPhase=iPhase-1
			else:
				 	
				chROT_STOP.putWait(0)
				chROT_SVEL.putWait(baseRotySpeed)
	
				if rotationStage=="Micos":
					chScanType.putWait(0)			
				print "Move Rotation to " + str(rotyMin)
				moveRotationWait(rotyMin)
				
				print "\033[1m"  ## bold
				print "Acquiring post flats " + str(iPhase+1)
				print "\033[0m"	 ## back to normal
		
				print "Saving post flat images " + str(int(numberOfDarks+iPhase*(2*numberOfFlats+numberOfProjections)+numberOfFlats+numberOfProjections+1)) + "-" + str(int(numberOfDarks+(iPhase+1)*(2*numberOfFlats+numberOfProjections)))
				chCCDCAM_FILENR.putWait(numberOfDarks+iPhase*(2*numberOfFlats+numberOfProjections)+numberOfFlats+numberOfProjections+1)
				chCCDCAM_SAVESTART.putWait(1)
				chCCDCAM_SAVESTOP.putWait(numberOfFlats)

				print "Moving the sample out of beam ..."
				chSampleX.move(xLinOut)
				chSampleX.wait(poll=1)
				
				if scanType=="7":
					if rotationStage=="Micos":
						chScanType.putWait(0)
						chCCDCAM_DELAY.putWait(delayForFlats)
					else:
						if millisecondShutter=="Cam-Ctrl":
							chCCDCAM_DELAY.putWait(stabilizationTime)
					chCCDCAM_SET_PARAM.putWait("SET")
					
				# Set the channel of the tomography panel
				chCameraStatus.putWait("Acquiring")
	
				# Clear buffer
				chCCDCAM_CLEARMEM.putWait("CLEAR")
						
				print "Send trigger to the camera"
				snap_dpc()

				chCameraStatus.putWait("Idle")
				print "Post flats acquisition done!"
				
				if scanType=="7":
					if millisecondShutter=="Cam-Ctrl":
						chCCDCAM_DELAY.putWait(0)
						chCCDCAM_SET_PARAM.putWait("SET")
			
			print "Moving back to initial conditions ..."
			print "Set rotation speed back to " + str(baseRotySpeed)
			if rotationStage=="Aerotech":
				chROT_STOP.putWait(0)
			chROT_SVEL.putWait(baseRotySpeed)
			print "Move Rotation to " + str(rotyMin)
			moveRotationWait(rotyMin)

			if scanPause==1:
				scanPause=0
				print "PHASE " + str(iPhase)
				if pauseFound==0:
					pauseFound=1
					iPhase=iPhase-1
		iPhase+=1
			
		
	print "\033[1m"  ## bold
	print "Grating stepping finished"
	print "\033[0m"	 ## back to normal
	
	print "Moving back to initial conditions ..."

	if scanInterruption==0:
		chComputeSinograms.putWait(1)
	
	# Close the shutter and put sample back!
	
	if operationMode!=2:
		if crystal1Pitch>-100:
			print "Dump the beam by moving OP_FILTER 4 to -22.0 mm ..."
			chOPFilter4.move(-22);chOPFilter4.wait(poll=1)
		else:
			print "Dump the beam by moving OP_FILTER 4 to -12.0 mm ..."
			chOPFilter4.move(-12);chOPFilter4.wait(poll=1)
	else:
		if crystal1Pitch>-100:
			print "Dump the beam by moving OP_FILTER 4 to -22.0 mm ..."
		else:
			print "Dump the beam by moving OP_FILTER 4 to -12.0 mm ..."
				
	print "Set rotation speed back to " + str(baseRotySpeed)
	#if rotationStage=="Aerotech":
	chROT_STOP.putWait(0)
	chROT_SVEL.putWait(baseRotySpeed)
	
	if rotationStage=="Micos":
		chScanType.putWait(0)			
	print "Move Rotation to " + str(rotyMin)
	moveRotationWait(rotyMin)
	print "Moving the sample out of beam ..."
	chSampleX.move(xLinOut);chSampleX.wait(poll=1)
	
	if operationMode==0:
		chPiezo.move(gridStart)
		chPiezo.wait(poll=1)
	print "Moving grating to " + str(gridStart)
		
	chScanTimeToGo.putWait(0)
	
	if scanType=="7" and rotationStage=="Aerotech":
		chBoxModeSelection.putWait("Custom")
		chROT_GACC.putWait(rotationAcceleration)
		chROT_DIRECT_MODE.putWait(1)
		chCCDCAM_TRIGGER.putWait("auto trigger")
		chROT_COUNTER.putWait(0)

	FILE = open(logFile,"a")	
	FILE.write("DPC-TOMOGRAPHIC SCAN FINISHED at " + str(time.asctime(time.localtime(time.time())))+"\n")
	FILE.close()
	
	# Logging
	tree = ET.parse(databaseFile)
	sample = tree.getroot()
	scan = sample.find("./pointOfInterest/scan")
	endDate=ET.Element("endDate")
	endDate.text=str(time.asctime(time.localtime(time.time()))) 
	scan.append(endDate)
	tree.write(databaseFile)

	command = "cp " + logFile + " " + sampleTifPath
	os.system(command)
	command = "ln " + sampleTifPath + "/" + filePrefix + ".log " + logPath
	os.system(command)
	command = "rm " + logFile
	os.system(command)
	
	if scanInterruption==0:
		command = "curl -X PUT -H \"Content-Type: application/xml\" -d @\"" + databaseFile + "\" http://x02da-www-1:8080/ch.psi.epms.web/rs/epms/upload"
		os.system(command)
		command = "cp " + databaseFile + " " + sampleTifPath
		os.system(command)
		command = "ln " + sampleTifPath + "/" + filePrefix + ".xml " + logPath
		os.system(command)
		command = "rm " + databaseFile
		os.system(command)
	else:
		chScanInterruption.putWait(1)
	
	print "Set STOREMODE and RECMODE back to Recorder and Ring Buffer (for preview purposes)"
	chCCDCAM_STOREMODE.putWait("Recorder")
	chCCDCAM_RECMODE.putWait("Ring Buffer")
	chCCDCAM_SET_PARAM.putWait("SET")
	print "Fifo mode OFF"
	
	# Set the scan status flag to Idle
	chExperimentStatus.putWait("Idle")
	chPause.putWait(0)
	

# ---------------------------------- Main ---------------------------------------------
global logFile,sampleTifPath,logPath,databaseFile,operationMode

beamline="X02DA"

'''
operationMode=0		Production mode
operationMode=1		Production mode during machine/shutdown
operationMode=2		Testing on second endstation during operation
'''

operationMode=0
standardChannelDefinition(operationMode)

# Camera channel definition
usedServer=chServer.getw()
if usedServer==0:
	cameraPrefix="CCDCAM"
	SERVERNR="1"
elif usedServer==1:
	cameraPrefix="CCDCAM2"
	SERVERNR="2"
else:
	print "Server " + str(usedServer) + " has not been implemented yet!"
	sys.exit(0)
print "Used server: " + SERVERNR	
cameraChannelDefinition(beamline,cameraPrefix)

# Endstation definition
usedEndstation=chEndstation.getw()
if usedEndstation==0:
	endstationPrefix="ES1"
	rotationStage="Aerotech"
elif usedEndstation==1:
	endstationPrefix="ES2"
	rotationStage="Micos"
else:
	print "Endstation " + str(usedEndstation) + " has not been implemented yet!"
	sys.exit(0)
print "Used endstation: " + endstationPrefix	
rotationStageDefinition(rotationStage,endstationPrefix,beamline)

# Initialize
chGo.putWait(0)
chPause.putWait(0)
chExperimentStatus.putWait("Idle",req_type=ca.DBF_STRING)
chCameraStatus.putWait("Idle",req_type=ca.DBF_STRING)

oldSamplename="Null"

while (1):

	# Scan type
	scanType=sys.argv[1]

	scango=chGo.getw() 

	if scanType == "2":
		print "\033[1m"  ## bold
		print "Fast Mode ON"
		print "Waiting for your toggle on the panel to start the scan"
		print "\033[0m"	 ## back to normal
	elif scanType == "5":
		print "\033[1m"  ## bold
		print "DPC Fast Mode ON"
		print "Waiting for your toggle on the panel to start the scan"
		print "\033[0m"	 ## back to normal
	elif scanType == "6":
		print "\033[1m"  ## bold
		print "Snap&Step Mode On"
		print "Waiting for your toggle on the panel to start the scan"
		print "\033[0m"	 ## back to normal
	elif scanType == "7":
		print "\033[1m"  ## bold
		print "DPC Snap&Step Mode On"
		print "Waiting for your toggle on the panel to start the scan"
		print "\033[0m"	 ## back to normal
	elif scanType == "-h":
		show_help()
	else:
		show_help()
 
 	while scango!=1:
		time.sleep(0.1)
		scango=chGo.getw()
		
	# Stop camera if running and reset rotation stage features
	chCCDCAM_CAMERA.putWait("OFF",req_type=ca.DBF_STRING)
	if rotationStage=="Aerotech":
		chBoxModeSelection.putWait("Custom")
		chROT_SNAP_START.putWait(0)
		chROT_SNAP_OFFSET.putWait(0)
		chROT_DIRECT_MODE.putWait(1)
	
	# Scan interruption flag
	chScanInterruption.putWait(0)
	chComputeSinograms.putWait(0)
	
	# Filename prefix for ccd images
	filePrefix=chFilePrefix.getw()
	baseName=filePrefix
	
	# Sample ROI (for robot operation and stacked scans)
	roi=chRoi.getw()
	if roi=="":
		roi="P1" # For database
		filePrefix=baseName
	else:
		filePrefix=baseName+"_"+roi
		
	if filePrefix==oldSamplename:
		print "\033[1m"  ## bold
		print ""
		print "Current samplename is the same as the one of the previous scan!"
		print "Please change the samplename and start the scan again."
		print ""
		print "\033[0m"	 ## back to normal
		scanType="10"
	oldSamplename=filePrefix
	
	# Check for empty spaces in the samplename
	filePrefixList=filePrefix.split(" ")
	if len(filePrefixList)>1:
		print "\033[1m"  ## bold
		print ""
		print "The samplename must not contain spaces!!!"
		print ""
		print "\033[0m"	 ## back to normal
		scanType="10"		
				
	chFilePrefix.putWait(filePrefix)
	
	# Exposure time (in s)
	exposure=chExposure.getw()
	chCCDCAM_EXPOSURE.putWait(exposure)
	chCCDCAM_SET_PARAM.putWait("SET")
	# Delay time (in s)
	delayStart=chCCDCAM_DELAY.getw()
	# Rotation scan values
	rotyMin=chRotyMin.getw()
	rotyMax=chRotyMax.getw()
	rotationAxisPosition=chRotationAxisPosition.getw(ca.DBF_STRING)
	
	# Region of interest
	ccdXStart=chCCDCAM_REGIONX_START.getw()
	ccdXEnd=chCCDCAM_REGIONX_END.getw()
	ccdYStart=chCCDCAM_REGIONY_START.getw()
	ccdYEnd=chCCDCAM_REGIONY_END.getw()
	
	# Values for in and out of beam position
	xLinIn=chXLinIn.getw()
	xLinOut=chXLinOut.getw()
	
	# Number of darks
	numberOfDarks=chNumberOfDarks.getw()
	# Number of flats
	numberOfFlats=chNumberOfFlats.getw()
	# Number of projections
	numberOfProjections=chNumberOfProjections.getw()
	
	if math.fabs(rotyMax-rotyMin)==360:
		if numberOfProjections%2==0 and rotationAxisPosition!="Standard":
			print "\033[1m"  ## bold
			print ""
			print "360 degrees stiched scan: an odd number of projections is required"
			print "The number of projections has been incremented by 1"
			print ""
			print "\033[0m"	 ## back to normal
			numberOfProjections=numberOfProjections+1
			print "Number of projections " + str(numberOfProjections)
			chNumberOfProjections.putWait(numberOfProjections)
		if numberOfProjections%2!=0 and rotationAxisPosition=="Standard":
			print "\033[1m"  ## bold
			print ""
			print "360 degrees standard scan: an even number of projections is required"
			print "The number of projections has been incremented by 1"
			print ""
			print "\033[0m"	 ## back to normal
			numberOfProjections=numberOfProjections+1
			print "Number of projections " + str(numberOfProjections)
			chNumberOfProjections.putWait(numberOfProjections)
			
	# Sample coordinatesLog
	sampleX=chSampleX.get_position(dial=1)
	sampleY=chSampleY.getw()
	sampleZ=chSampleZ.get_position(dial=1)
	sampleXX=chSampleXX.get_position(dial=1)
	sampleZZ=chSampleZZ.get_position(dial=1)
	
	# Microscope coordinates
	microscopeX=chMicroscopeX.get_position(dial=1)
	microscopeY=chMicroscopeY.get_position(dial=1)
	microscopeZ=chMicroscopeZ.get_position(dial=1)

	# For DPC
	if scanType=="5" or scanType=="7":
		piezoOffset=50
		piezoCalibration=1.0
		# Grid start point
		gridStartRaw=chGridStartRaw.getw()
		gridEndRaw=chGridEndRaw.getw()
		gridStart=(gridStartRaw*piezoCalibration)+piezoOffset
		gridEnd=(gridEndRaw-gridStartRaw)*piezoCalibration+gridStart
		gridNSteps=chGridNSteps.getw()
		gridNPeriods=chGridNPeriods.getw()
		
	if scanType=="6" or scanType=="7":
		triggerDelay=chTriggerDelay.getw()
		if rotationStage=="Aerotech":
			chROT_STAB_TIME.putWait(triggerDelay)
		elif rotationStage=="Micos":
			chSystemOffset.putWait(triggerDelay)
		
	millisecondShutter=chMillisecondShutter.getw(req_type=ca.DBF_STRING)
		
	# Read user id
	userID=chUserID.getw()
	
	# Read machine and beamline parameters
	if operationMode==0:
		ringCurrentStart=chRingCurrentStatus.getw()
	else:
		ringCurrentStart=chRingCurrentStartFake.getw()
	if ringCurrentStart<10:
		print "\033[1m"  ## bold
		print ""
		print "Ring current is too low to start a scan!!"
		print ""
		print "\033[0m"	 ## back to normal
		chGo.putWait(0)
		scanType="10"
		
	# Energy
	crystal1Pitch=chCrystal1Pitch.get_position()
	if crystal1Pitch>-100:
		beamEnergy="Polychromatic radiation"
	else:
		beamEnergy=chBeamEnergy.getw()
		stripe=chStripe.getw(req_type=ca.DBF_STRING)
	
	# Filters
	FEFilter=chFEFilter.getw(req_type=ca.DBF_STRING)
	OPFilter1=chOPFilter1.getw(req_type=ca.DBF_STRING)
	OPFilter2=chOPFilter2.getw(req_type=ca.DBF_STRING)
	OPFilter3=chOPFilter3.getw(req_type=ca.DBF_STRING)
		
	# Read detector parameters
	camera=chCamera.getw(req_type=ca.DBF_STRING)
	microscope=chMicroscope.getw(req_type=ca.DBF_STRING)
	magnification=chMagnification.getw()
	scintillator=chScintillator.getw()
	pixelSize=chPixelSize.getw()
	
	# Path variables
	storage=chStorage.getw()
	
	# Define the temporary path for logging
	loggingBasePath="/sls/X02DA/data/e" + userID + "/public/"
	logFile=loggingBasePath + filePrefix + ".log"
	databaseFile=loggingBasePath + filePrefix + ".xml"		
	
	# Sample path
	sampleBasePath="/sls/X02DA/data/e" + userID + "/" + storage + "/" + filePrefix + "/"
	sampleTifPath=sampleBasePath + "tif"
	
	# Log path
	logPath="/sls/X02DA/data/e" + userID + "/" + storage + "/log"
	
	# Folder name for Camera Server X:// is hardcoded!!!
	folderName="X:/" + storage + "/" + filePrefix + "/tif/\0"
	if len(folderName)>255:
		print "\033[1m"  ## bold
		print ""
		print "The samplename is too long!!"
		print ""
		print "\033[0m"	 ## back to normal
		scanType="10"		
	
	if scanType!="10":
		if os.path.isdir(logPath):
			pass
		else:
			os.mkdir(logPath)
		if os.path.isdir(sampleBasePath):
			print "\033[1m"  ## bold
			print ""
			print "The samplename " + filePrefix + " already exist!!"
			print ""
			print "\033[0m"	 ## back to normal
			scanType="10"		
		else:
			os.mkdir(sampleBasePath)
		if os.path.isdir(sampleTifPath):
			pass
		else:
			os.mkdir(sampleTifPath)
	
	if scanType!="10":
	
		print "User ID : e" + str(userID)
		if scanType=="2":
			print "FAST-TOMO scan of sample " + filePrefix + " started on " + str(time.asctime(time.localtime(time.time())))
		elif scanType=="5" or scanType=="7":
			print "DPC scan of sample " + filePrefix + " started on " + str(time.asctime(time.localtime(time.time())))
        	else:
			print "SNAP&STEP-TOMO scan of sample " + filePrefix + " started on " + str(time.asctime(time.localtime(time.time())))
		
		print "--------------------Beamline Settings-------------------------"
		print "Ring current [mA]            : %3.3f" % ringCurrentStart
		if crystal1Pitch>-100:
			print "Beam energy                  : " + str(beamEnergy)
		else:
			print "Beam energy  [keV]           : %2.3f" % beamEnergy
			print "Monostripe                   : " + str(stripe)
		print "FE-Filter                    : " + str(FEFilter)
		print "OP-Filter 1                  : " + str(OPFilter1)
		print "OP-Filter 2                  : " + str(OPFilter2)
		print "OP-Filter 3                  : " + str(OPFilter3)
		print "--------------------Detector Settings-------------------------"
		print "Camera                       : " + str(camera)
		print "Microscope                   : " + str(microscope)
		print "Magnification                : " + str(magnification)
		print "Scintillator                 : " + str(scintillator)
		print "Exposure time [ms]           : " + str(exposure)
		if scanType=="2" or scanType=="5":
			print "Delay time [ms]              : " + str(delayStart)
		if (scanType=="6" or scanType=="7") and rotationStage=="Aerotech":
			stabilizationTime=chROT_STAB_TIME.getw()
			print "Stabilization time [ms]      : " + str(stabilizationTime)
		
		if millisecondShutter=="IOC-Ctrl":
			print "Millisecond shutter          : not used"
		else:
			print "Millisecond shutter          : used"
		print "X-ROI                        : " + str(int(ccdXStart)) + " - " +str(int(ccdXEnd))
		print "Y-ROI                        : " + str(int(ccdYStart)) + " - " +str(int(ccdYEnd))
		print "Actual pixel size [um]       : " + str(pixelSize)
		print "------------------------Scan Settings-------------------------"
		print "Sample folder                : " + str(sampleBasePath)
		print "File Prefix                  : " + str(filePrefix)
		print "Number of projections        : " + str(int(numberOfProjections))
		print "Number of darks              : " + str(int(numberOfDarks))
		print "Number of flats              : " + str(int(numberOfFlats))
		print "Number of inter-flats        : 0"
		print "Flat frequency               : 0"
		print "Rot Y min position  [deg]    : " + str(rotyMin)
		print "Rot Y max position  [deg]    : " + str(rotyMax)
		print "Rotation axis position       : " + str(rotationAxisPosition)
		if numberOfProjections!=0:
			print "Angular step [deg]           : " + str((rotyMax-rotyMin)/(numberOfProjections-1))
		else:
			print "Angular step [deg]           : 0"
		print "Sample In   [um]             : " + str(xLinIn)
		print "Sample Out  [um]             : " + str(xLinOut)
		print "-----------------------Sample coordinates---------------------"
		print "X-coordinate                 : " + str(sampleX)
		print "Y-coordinate                 : " + str(sampleY)
		print "Z-coordinate                 : " + str(sampleZ)
		print "XX-coordinate                : " + str(sampleXX)
		print "ZZ-coordinate                : " + str(sampleZZ)
 		print "-----------------------Microscope coordinates---------------------"
		print "X-coordinate                 : " + str(microscopeX)
		print "Y-coordinate                 : " + str(microscopeY)
		print "Z-coordinate                 : " + str(microscopeZ)
		if scanType=="5" or scanType=="7":
			print "--------------------Interferometer Settings-------------------"
			print "Grid start position [um]     : " + str(gridStartRaw)
 			print "Grid end position [um]       : " + str(gridEndRaw)
			print "Grid step                    : " + str(gridNSteps)
			print "Grid period                  : " + str(gridNPeriods)
		print "--------------------------------------------------------------"
		
		
		FILE = open(logFile,"a")
		FILE.write("User ID : e" + userID + "\n")
		if scanType=="2":
			FILE.write("FAST-TOMO scan of sample " + filePrefix + " started on " + str(time.asctime(time.localtime(time.time()))) + "\n")
		elif scanType=="5" or scanType=="7":
			FILE.write("DPC-TOMO scan of sample " + filePrefix + " started on " + str(time.asctime(time.localtime(time.time()))) + "\n")
		else:
			FILE.write("SNAP&STEP-TOMO scan of sample " + filePrefix + " started on " + str(time.asctime(time.localtime(time.time()))) + "\n")		
		FILE.write("--------------------Beamline Settings-------------------------\n")
		FILE.write("Ring current [mA]           : %3.3f\n" % ringCurrentStart)
		if crystal1Pitch>-100: 
			FILE.write("Beam energy                 : " + beamEnergy + "\n")
		else:
			FILE.write("Beam energy [keV]           : %2.3f\n" % beamEnergy)
			FILE.write("Monostripe                  : " + str(stripe) + "\n")
		FILE.write("FE-Filter                   : " + str(FEFilter) + "\n")
		FILE.write("OP-Filter 1                 : " + str(OPFilter1) + "\n")
		FILE.write("OP-Filter 2                 : " + str(OPFilter2) + "\n")
		FILE.write("OP-Filter 3                 : " + str(OPFilter3) + "\n")
		FILE.write("--------------------Detector Settings-------------------------\n")
		FILE.write("Camera                      : " + str(camera) + "\n")
		FILE.write("Microscope                  : " + str(microscope) + "\n")
		FILE.write("Magnification               : " + str(magnification) + "\n")
		FILE.write("Scintillator                : " + str(scintillator) + "\n")
		FILE.write("Exposure time [ms]          : " + str(exposure) + "\n")
		if scanType=="2" or scanType=="5":
			FILE.write("Delay time [ms]             : " + str(delayStart) + "\n")
		if (scanType=="6" or scanType=="7") and rotationStage=="Aerotech":
			FILE.write("Stabilization time [ms]     : " + str(stabilizationTime) + "\n")
		if millisecondShutter=="IOC-Ctrl":
			FILE.write("Millisecond shutter [ms]    : not used\n")
		else:
			FILE.write("Millisecond shutter [ms]    : used\n")
		FILE.write("X-ROI                       : " + str(int(ccdXStart)) + " - " + str(int(ccdXEnd)) + "\n")
		FILE.write("Y-ROI                       : " + str(int(ccdYStart)) + " - " + str(int(ccdYEnd)) + "\n")
		FILE.write("Actual pixel size [um]      : " + str(pixelSize) + "\n")
		FILE.write("------------------------Scan Settings-------------------------\n")
		FILE.write("Sample folder               : " + sampleBasePath + "\n")
		FILE.write("File Prefix                 : " + str(filePrefix) + "\n")
		FILE.write("Number of projections       : " + str(int(numberOfProjections)) + "\n")
		FILE.write("Number of darks             : " + str(int(numberOfDarks)) + "\n")
		FILE.write("Number of flats             : " + str(int(numberOfFlats)) + "\n")
		FILE.write("Number of inter-flats       : 0\n")
		FILE.write("Flat frequency              : 0\n")
		FILE.write("Rot Y min position  [deg]   : " + str(rotyMin) + "\n")
		FILE.write("Rot Y max position  [deg]   : " + str(rotyMax) + "\n")
		FILE.write("Rotation axis position      : " + str(rotationAxisPosition) + "\n")
		if numberOfProjections!=0:
			FILE.write("Angular step [deg]          : %3.3f\n" % ((rotyMax-rotyMin)/(numberOfProjections-1)))
		else:
			FILE.write("Angular step [deg]          : 0")
		FILE.write("Sample In   [um]            : %5.0f\n" % xLinIn)
		FILE.write("Sample Out  [um]            : %5.0f\n" % xLinOut)
		FILE.write("-----------------------Sample coordinates---------------------\n")
		FILE.write("X-coordinate                : %5.2f\n" % sampleX)
		FILE.write("Y-coordinate                : %5.2f\n" % sampleY)
		FILE.write("Z-coordinate                : %5.2f\n" % sampleZ)
		FILE.write("XX-coordinate               : %5.2f\n" % sampleXX)
		FILE.write("ZZ-coordinate               : %5.2f\n" % sampleZZ)
		FILE.write("-----------------------Microscope coordinates---------------------\n")
		FILE.write("X-coordinate                : %5.2f\n" % microscopeX)
		FILE.write("Y-coordinate                : %5.2f\n" % microscopeY)
		FILE.write("Z-coordinate                : %5.2f\n" % microscopeZ)
		if scanType=="5" or scanType=="7":
			FILE.write("--------------------Interferometer Settings-------------------\n")
			FILE.write("Grid start position [um]    : " + str(gridStartRaw) + "\n")
			FILE.write("Grid end position [um]      : " + str(gridEndRaw) + "\n")
			FILE.write("Grid step                   : " + str(int(gridNSteps)) + "\n")
			FILE.write("Grid period                 : " + str(int(gridNPeriods)) + "\n")
		FILE.write("--------------------------------------------------------------\n")		
		FILE.close()
		
		# Write xml file
		sample=ET.Element("sample")
		name=ET.SubElement(sample,"name")
		name.text=baseName
		userid=ET.SubElement(sample,"userid")
		userid.text="e" + str(userID)
		pointOfInterest=ET.SubElement(sample,"pointOfInterest")
		name1=ET.SubElement(pointOfInterest,"name")
		name1.text=roi
		coordinates=ET.SubElement(pointOfInterest,"coordinates")
		x=ET.SubElement(coordinates,"x")
		x.text=str('{0:.2f}'.format(sampleX))	 
		y=ET.SubElement(coordinates,"y")
		y.text=str('{0:.2f}'.format(sampleY))	 
		z=ET.SubElement(coordinates,"z")
		z.text=str('{0:.2f}'.format(sampleZ))	 
		xx=ET.SubElement(coordinates,"xx")
		xx.text=str('{0:.2f}'.format(sampleXX))	 
		zz=ET.SubElement(coordinates,"zz")
		zz.text=str('{0:.2f}'.format(sampleZZ))
		coordinateSystem=ET.SubElement(coordinates,"coordinateSystem")
		coordinateSystem.text="beamline"
		scan=ET.SubElement(pointOfInterest,"scan")
		scanTYPE=ET.SubElement(scan,"scanType")
		if scanType=="2":
			scanTYPE.text="FAST-TOMO"
		elif scanType=="6":
			scanTYPE.text="SNAP-AND-STEP-TOMO"
		else:
			scanTYPE.text="DPC-TOMO"
		startDate=ET.SubElement(scan,"startDate")
		startDate.text=str(time.asctime(time.localtime(time.time()))) 
		beamlineParameters=ET.SubElement(scan,"beamlineParameters")
		parameter=ET.SubElement(beamlineParameters,"parameter")
		parameter.text=str('{0:.3f}'.format(ringCurrentStart))
		parameter.set('name','Ring current')
		parameter.set('unit','mA')
		parameter1=ET.SubElement(beamlineParameters,"parameter")
		if crystal1Pitch>-100:
			parameter1.text=beamEnergy
			parameter1.set('name','Beam energy')
		else:
			parameter1.text=str('{0:.3f}'.format(beamEnergy))
			parameter1.set('name','Beam energy')
			parameter1.set('unit','keV')
			parameter2=ET.SubElement(beamlineParameters,"parameter")
			parameter2.text=stripe
			parameter2.set('name','Monostripe')
		parameter3=ET.SubElement(beamlineParameters,"parameter")
		parameter3.text=FEFilter
		parameter3.set('name','FE-Filter')
		parameter4=ET.SubElement(beamlineParameters,"parameter")
		parameter4.text=OPFilter1
		parameter4.set('name','OP-Filter1')
		parameter5=ET.SubElement(beamlineParameters,"parameter")
		parameter5.text=OPFilter2
		parameter5.set('name','OP-Filter2')
		parameter6=ET.SubElement(beamlineParameters,"parameter")
		parameter6.text=OPFilter3
		parameter6.set('name','OP-Filter3')
		detectorParameters=ET.SubElement(scan,"detectorParameters")
		parameter7=ET.SubElement(detectorParameters,"parameter")
		parameter7.text=camera
		parameter7.set('name','Camera')
		parameter8=ET.SubElement(detectorParameters,"parameter")
		parameter8.text=microscope
		parameter8.set('name','Microscope')
		parameter9=ET.SubElement(detectorParameters,"parameter")
		parameter9.text=str(magnification)
		parameter9.set('name','Objective')
		parameter10=ET.SubElement(detectorParameters,"parameter")
		parameter10.text=scintillator
		parameter10.set('name','Scintillator')
		parameter11=ET.SubElement(detectorParameters,"parameter")
		parameter11.text=str(int(exposure))
		parameter11.set('name','Exposure time')
		parameter11.set('unit','ms')
		if scanType=="2" or scanType=="5":
			parameter12=ET.SubElement(detectorParameters,"parameter")
			parameter12.text=str(int(delayStart))
			parameter12.set('name','Delay time')
			parameter12.set('unit','ms')
		if (scanType=="6" or scanType=="7") and rotationStage=="Aerotech":
			parameter12a=ET.SubElement(detectorParameters,"parameter")
			parameter12a.text=str(int(stabilizationTime))
			parameter12a.set('name','Stabilization time')
			parameter12a.set('unit','ms')
		if millisecondShutter=="IOC-Ctrl":
			parameter13=ET.SubElement(detectorParameters,"parameter")
			parameter13.text="not used"
			parameter13.set('name','Millisecond shutter')
		else:
			parameter13=ET.SubElement(detectorParameters,"parameter")
			parameter13.text="used"
			parameter13.set('name','Millisecond shutter')
		parameter14=ET.SubElement(detectorParameters,"parameter")
		parameter14.text=str(int(ccdXStart))
		parameter14.set('name','X-ROI Start')
		parameter15=ET.SubElement(detectorParameters,"parameter")
		parameter15.text=str(int(ccdXEnd))
		parameter15.set('name','X-ROI End')
		parameter16=ET.SubElement(detectorParameters,"parameter")
		parameter16.text=str(int(ccdYStart))
		parameter16.set('name','Y-ROI Start')
		parameter17=ET.SubElement(detectorParameters,"parameter")
		parameter17.text=str(int(ccdYEnd))
		parameter17.set('name','Y-ROI End')
		parameter18=ET.SubElement(detectorParameters,"parameter")
		parameter18.text=str('{0:.2f}'.format(pixelSize))
		parameter18.set('name','Actual pixel size')
		parameter18.set('unit','um')
		parameter18a=ET.SubElement(detectorParameters,"parameter")
		parameter18a.text=str('{0:.2f}'.format(microscopeX))
		parameter18a.set('name','Microscope x position')
		parameter18a.set('unit','mm')
		parameter18b=ET.SubElement(detectorParameters,"parameter")
		parameter18b.text=str('{0:.2f}'.format(microscopeY))
		parameter18b.set('name','Microscope y position')
		parameter18b.set('unit','mm')
		parameter18b=ET.SubElement(detectorParameters,"parameter")
		parameter18b.text=str('{0:.2f}'.format(microscopeZ))
		parameter18b.set('name','Microscope z position')
		parameter18b.set('unit','mm')
		scanParameters=ET.SubElement(scan,"scanParameters")
		parameter19=ET.SubElement(scanParameters,"parameter")
		parameter19.text=sampleBasePath
		parameter19.set('name','Sample folder')
		parameter20=ET.SubElement(scanParameters,"parameter")
		parameter20.text=filePrefix
		parameter20.set('name','File Prefix')
		parameter21=ET.SubElement(scanParameters,"parameter")
		parameter21.text=str(int(numberOfProjections))
		parameter21.set('name','Number of projections')
		parameter22=ET.SubElement(scanParameters,"parameter")
		parameter22.text=str(int(numberOfDarks))
		parameter22.set('name','Number of darks')
		parameter23=ET.SubElement(scanParameters,"parameter")
		parameter23.text=str(int(numberOfFlats))
		parameter23.set('name','Number of flats')
		parameter24=ET.SubElement(scanParameters,"parameter")
		parameter24.text="0"
		parameter24.set('name','Number of inter-flats')
		parameter24=ET.SubElement(scanParameters,"parameter")
		parameter24.text="0"
		parameter24.set('name','Flat frequency')
		parameter18=ET.SubElement(scanParameters,"parameter")
		parameter18.text=str('{0:.3f}'.format(rotyMin))
		parameter18.set('name','Rot Y min position')
		parameter18.set('unit','deg')
		parameter19=ET.SubElement(scanParameters,"parameter")
		parameter19.text=str('{0:.3f}'.format(rotyMax))
		parameter19.set('name','Rot Y max position')
		parameter19a=ET.SubElement(scanParameters,"parameter")
		parameter19a.text=str(rotationAxisPosition)
		parameter19a.set('name','Rotation axis position')
		if numberOfProjections!=0:
			parameter20=ET.SubElement(scanParameters,"parameter")
			parameter20.text=str('{0:.3f}'.format((rotyMax-rotyMin)/(numberOfProjections-1)))
			parameter20.set('name','Angular step')
			parameter20.set('unit','deg')
		else:
			parameter20=ET.SubElement(scanParameters,"parameter")
			parameter20.text="0"
			parameter20.set('name','Angular step')
			parameter20.set('unit','deg')
		parameter21=ET.SubElement(scanParameters,"parameter")
		parameter21.text=str(int(xLinIn))
		parameter21.set('name','Sample In')
		parameter21.set('unit','um')
		parameter22=ET.SubElement(scanParameters,"parameter")
		parameter22.text=str(int(xLinOut))
		parameter22.set('name','Sample Out')
		parameter22.set('unit','um')
		if scanType=="5" or scanType=="7":
			parameter23=ET.SubElement(scanParameters,"parameter")
			parameter23.text=str('{0:.3f}'.format(gridStartRaw))
			parameter23.set('name','Grid start position')
			parameter23.set('unit','um')
			parameter24=ET.SubElement(scanParameters,"parameter")
			parameter24.text=str('{0:.3f}'.format(gridEndRaw))
			parameter24.set('name','Grid end position')
			parameter24.set('unit','um')
			parameter25=ET.SubElement(scanParameters,"parameter")
			parameter25.text=str(int(gridNSteps))
			parameter25.set('name','Grid step')
			parameter26=ET.SubElement(scanParameters,"parameter")
			parameter26.text=str(int(gridNPeriods))
			parameter26.set('name','Grid period')

		# Wrap it in an ElementTree instance, and save as XML
		tree=ET.ElementTree(sample)
		tree.write(databaseFile)
		chCCDCAM_FILENAME.putWait(filePrefix + "\0",req_type=ca.DBF_CHAR)
		chCCDCAM_FILEPATH.putWait(folderName,req_type=ca.DBF_CHAR)
		filepathSevr=chCCDCAM_FILEPATHSEVR.getw()
		filepathStat=chCCDCAM_FILEPATHSTAT.getw()
		while filepathSevr!=0 or filepathStat!=0:
			print "I am setting the filepath again"
			print filepathSevr
			print filepathStat
			chCCDCAM_FILEPATH.putWait(folderName,req_type=ca.DBF_CHAR)
		        filepathSevr=chCCDCAM_FILEPATHSEVR.getw()
		        filepathStat=chCCDCAM_FILEPATHSTAT.getw()
		
		# Make the scan
		if scanType=="2" or scanType=="6":
			fasttomoscan(rotyMin,rotyMax,numberOfProjections,exposure,xLinIn,xLinOut,numberOfDarks,numberOfFlats,crystal1Pitch,scanType,millisecondShutter,rotationStage)
		else:
			fastdpcscan(rotyMin,rotyMax,numberOfProjections,exposure,xLinIn,xLinOut,numberOfDarks,numberOfFlats,gridStart,gridEnd,gridNSteps,crystal1Pitch,scanType,millisecondShutter,rotationStage)
	
	# Set the scan start button to Stop
	chGo.putWait(0)
	chFilePrefix.putWait(baseName)
	chCCDCAM_DELAY.putWait(delayStart)
