From 38cfea4865ac6150902245ede3806341a9bb593e Mon Sep 17 00:00:00 2001 From: koennecke Date: Tue, 11 Apr 2006 08:03:15 +0000 Subject: [PATCH] - Conescan working now - Removed old NETReadTillterm SKIPPED: psi/libpsi.a psi/tasdriveo.c --- cone.c | 39 ++++++++++--------- cone.h | 7 ++-- cone.w | 5 +++ doc/user/Conescan.html | 77 ++++++++++++++++++++++++++++++++++++ doc/user/tricsingle.htm | 25 +++++++++--- doc/user/tricsman | 4 +- drive.c | 25 ++++++++++-- mcstas/dmc/vdmccom.tcl | 75 +++++++++++++++++++++++++++++++++-- network.c | 86 +---------------------------------------- network.h | 4 +- remob.c | 2 +- rs232controller.c | 4 +- tcl/sicstcldebug.tcl | 1 + 13 files changed, 230 insertions(+), 124 deletions(-) create mode 100644 doc/user/Conescan.html diff --git a/cone.c b/cone.c index ee6aeb6f..4fc4d5d9 100644 --- a/cone.c +++ b/cone.c @@ -34,6 +34,7 @@ static void ConeSaveStatus(void *data, char *name, FILE *fd){ fprintf(fd,"%s center %d\n", name,self->center); fprintf(fd,"%s target %f %f %f\n", name, self->target.h, self->target.k, self->target.l); + fprintf(fd,"%s qscale %f \n", name, self->qScale); } /*=================== Drivable Interface ============================================================*/ static int ConeHalt(void *pData){ @@ -89,12 +90,11 @@ static MATRIX makeCsToPsiMatrix(reflection center, double lambda){ static long ConeSetValue(void *pData, SConnection *pCon, float fVal){ pConeData self = NULL; float fSet[4]; - double openingAngle, length, testAngle; - MATRIX csToPsi = NULL, B = NULL, newScat = NULL, cent; + double openingAngle, length; + MATRIX csToPsi = NULL, B = NULL, newScat = NULL; int status; reflection center; char buffer[131]; - double z1[3]; if(!SCMatchRights(pCon,usUser)){ return 0; @@ -129,27 +129,13 @@ static long ConeSetValue(void *pData, SConnection *pCon, float fVal){ * calculate scattering vector on cone and make its length * match the length of the apropriate scattering vector */ - length = scatteringVectorLength(B,self->target); + length = scatteringVectorLength(B,self->target) * self->qScale; newScat = calcConeVector(openingAngle, fVal, length, csToPsi); if(newScat == NULL){ SCWrite(pCon,"ERROR: fails to calculate cone vector",eError); return 0; } - - /** - * this is debugging code - */ - length = vectorLength(newScat); - z1FromAngles(self->ubi->hkl->fLambda,center.s2t,center.om,center.chi, - center.phi,z1); - cent = makeVectorInit(z1); - testAngle = angleBetween(cent,newScat); - snprintf(buffer,131,"OpeningAngle = %f, testAngle = %f, length = %f", - openingAngle,testAngle,length); - SCWrite(pCon,buffer,eWarning); - - - + /* * try to find setting angles for this vector */ @@ -240,6 +226,7 @@ static pConeData MakeConeMot(pUBCALC u){ self->pDriv->GetValue = ConeGetValue; self->ubi = u; self->pHkl = u->hkl; + self->qScale = 1.0; return self; } /*----------------------------------------------------------------------------------*/ @@ -288,6 +275,19 @@ int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char SCWrite(pCon,pBuffer,eValue); return 1; } + } else if(strcmp(argv[1],"qscale") == 0){ + if(argc > 2){ + if(!SCMatchRights(pCon,usUser)){ + return 0; + } + self->qScale = atof(argv[2]); + SCSendOK(pCon); + return 1; + } else { + snprintf(pBuffer,131,"%s.qscale = %f", argv[0], self->qScale); + SCWrite(pCon,pBuffer,eValue); + return 1; + } } else if (strcmp(argv[1],"target") == 0){ if(argc >= 5){ if(!SCMatchRights(pCon,usUser)){ @@ -296,6 +296,7 @@ int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char self->target.h = atof(argv[2]); self->target.k = atof(argv[3]); self->target.l = atof(argv[4]); + self->qScale = 1.; SCSendOK(pCon); return 1; } else { diff --git a/cone.h b/cone.h index e8a7ad74..b30ca423 100644 --- a/cone.h +++ b/cone.h @@ -19,9 +19,10 @@ typedef struct { pIDrivable pDriv; reflection target; float lastConeAngle; - pUBCALC ubi; - int center; - pHKL pHkl; + float qScale; + pUBCALC ubi; + int center; + pHKL pHkl; } coneData, *pConeData; /*----------------------------------------------------------------------*/ diff --git a/cone.w b/cone.w index 1ba9e5da..a64dc546 100644 --- a/cone.w +++ b/cone.w @@ -18,6 +18,7 @@ typedef struct { pIDrivable pDriv; reflection target; float lastConeAngle; + float qScale; pUBCALC ubi; int center; pHKL pHkl; @@ -28,6 +29,10 @@ The fields are: \item[pDes] The standard object descriptor \item[pDriv] The drivable interface which implements most of this modules functionality. + \item[lastConeAngle] The last cone angle set. Used instead of the not implemented + back calculation. + \item[qScale] An adaptor factor to multiply onto the scattering vector length. This is + in order to find the target reflection even if the lattice constants are inaccurate. \item[target] The target reflection of the cone. This determines the length of the scattering vector and the opening angle of the cone. \item[ubi] A pointer to the UBCALC module which holds things like lattice constants. diff --git a/doc/user/Conescan.html b/doc/user/Conescan.html new file mode 100644 index 00000000..92446c07 --- /dev/null +++ b/doc/user/Conescan.html @@ -0,0 +1,77 @@ + +Conescan.radi +

Conescan

+

A conescan is a possibly useful procedure when setting up a single crystal + diffraction experiment. The first thing which needs to be done when +starting a single crystal experiment is the determination of the UB +matrix. In order to do that at least two reflections need to be +located through a search procedure. Now, consider the situation when +one reflection has been found and indexed. Then it is known that other +reflections can be found on a cone + with an opening angle determined by the lattice parameters and the +indices of the target reflection around the first (center) +reflection. The SICS conescan module allows to do just that, do a scan +around a given center reflection. The syntax is: +

conescan list +
lists all the parameters of the conescan +
conescan cell +
prints the cell constants. +
conescan cell a b c alpha beta gamma +
sets new cell constants. +
conescan center +
prints the current values for the center reflection +
conescan center h k l +
uses h, k, l as the indices of the center + reflection. Motor positions are read from motors. +
conescan center h k l stt om chi phi +
defines a center position + complete with all angles. +
conescan target +
prints the current target for the conescan +
conescan target h k l +
defines the target indices for the conescan. +
conescan qscale +
prints the Q scale for the conescan. The conescan + module calculates the length of then scattering vector from the + lattice parameters and the indices. When the lattice constants are + only approximatly known it might be useful to vary the scattering + vector length for the conescan a little. This can be doen with the + qscale factor. +
conescan qscale value +
sets a new value for the qscale factor +
conescan run step mode preset +
starts a conescan with the nstep width + step, the couent mode mode and the preset preset. +
conescan run +
starts a conescan with defaults: step = .5, + mode = monitor, preset = 10000 +

This is the simple usage of the conescan. In fact cone is implemented +as a virtual motor. This means that arbitray scans can be performed on +cone as with any other motor. As with any other motor, cone can also +be driven to a cone angle. +

Implementation Reference

+

The conescan commands are just wrapper routines around the cone and +ubcalc module which actually work together to implement the +conescan. The ubcalc module, documented elsewhere, holds the cell +constants and the center reflection. +

The cone module does the actual cone calculation. Cone can be +configured with commands: +

cone center +
prints the number of the reflection in ubcalc to use as + a center. +
cone center num +
sets the reflection in ubcalc to use a the center + for driving on the cone. Set to 0 to use the first reflection in + ubcalc. +
cone target +
prints the target reflection indices for the cone. +
cone target h k l +
sets the target reflection indices. +
cone qscale +
prints the current value of the scattering vector scale. +
cone qscale val +
sets a value for the scaling factor for the + scattering vector. Values should be close to 1.0; + +
+ diff --git a/doc/user/tricsingle.htm b/doc/user/tricsingle.htm index 94cd2db1..49b995f7 100644 --- a/doc/user/tricsingle.htm +++ b/doc/user/tricsingle.htm @@ -18,7 +18,7 @@ to be solved are:

Locate Reflections

If you know x-ray single crystal diffractometers you'll expect sophisticated -reflection search procedures here. Nothing is available in this field in +reflection search procedures here. Little is available in this field in SICS. It was deemed inapropriate for neutron research. The first reflections must be found by hand. Something which may help in this is a quick scan facility which allows to run a motor and print counts while the motor is @@ -38,12 +38,27 @@ But it may help to locate the aproximate position of a peak.

Once a peak has been found, its position can be optimised and centered with the -peak optimiser. +peak optimiser. Dor not forget to put all +collimators in and to close all slits before optimizing. This is in +order to improve accuracy. +

+

+Once one reflection has been located, others might be located using the +conescan method when the lattice constants +are known. Do not forget to open all slits and to remove all +collimators for this. +

+

+If two reflections and the cell constants are known, a provisional UB +matrix may be calculated with the UBCALC +module. UBCALC can also calculate the UB matrix from three reflections +from scratch.

-The next thing to do is to store the reflection and find other ones. Once a -few reflections have been found, the need to be written to disk. This can be -accomplished with the object rliste which has the following subcommands: +With a prvisional UB matrix determined it is advisable to locate and +optimise another 20 reflections in order to do UB matrix +refinement. During this time, reflections may be stored using the +rliste module:

rliste clear
clears all entries from the list diff --git a/doc/user/tricsman b/doc/user/tricsman index a37d9f74..dc8a1f3f 100644 --- a/doc/user/tricsman +++ b/doc/user/tricsman @@ -48,6 +48,7 @@ Switzerland\\ %html system.htm 1 %html tricsingle.htm 1 %html optimise.htm 2 + \section{External FORTRAN 77 Programs} \subsection{INDEX} @@ -339,8 +340,9 @@ H H L 3 : 2H + L = 4n \end{verbatim} -%html mesure.htm 2 +%html Conescan.html 2 %html ubcalc.htm 2 +%html mesure.htm 2 %html hklscan.htm 2 %html tricspsd.htm 1 diff --git a/drive.c b/drive.c index 577b91b4..1ad01395 100644 --- a/drive.c +++ b/drive.c @@ -299,12 +299,15 @@ int DriveWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { + Tcl_Interp *tcl_interp; int iRet,i; + double dTarget; char pBueffel[512]; Status eOld; assert(pCon); assert(pSics); + tcl_interp = InterpGetTcl(pSics); /* check Status */ eOld = GetStatus(); @@ -340,7 +343,14 @@ SetStatus(eOld); return 0; } - iRet = Start2Run(pCon,pSics,argv[i],atof(argv[i+1])); + iRet = Tcl_GetDouble(tcl_interp, argv[i+1], &dTarget); + if (iRet == TCL_ERROR) { + SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError); + StopExe(GetExecutor(),"ALL"); + SetStatus(eOld); + return 0; + } + iRet = Start2Run(pCon,pSics,argv[i],dTarget); if(!iRet) { sprintf(pBueffel,"ERROR: cannot run %s to %s",argv[i],argv[i+1]); @@ -391,13 +401,15 @@ int RunWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { + Tcl_Interp *tcl_interp; int iRet, i; + double dTarget; char pBueffel[512]; Status eOld; assert(pCon); assert(pSics); - + tcl_interp = InterpGetTcl(pSics); /* check Status */ eOld = GetStatus(); @@ -431,7 +443,14 @@ SetStatus(eOld); return 0; } - iRet = Start2Run(pCon,pSics,argv[i],atof(argv[i+1])); + iRet = Tcl_GetDouble(tcl_interp, argv[i+1], &dTarget); + if (iRet == TCL_ERROR) { + SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError); + StopExe(GetExecutor(),"ALL"); + SetStatus(eOld); + return 0; + } + iRet = Start2Run(pCon,pSics,argv[i],dTarget); if(!iRet) { sprintf(pBueffel,"ERROR: cannot run %s to %s",argv[i],argv[i+1]); diff --git a/mcstas/dmc/vdmccom.tcl b/mcstas/dmc/vdmccom.tcl index 2e38ae18..4500cfa0 100644 --- a/mcstas/dmc/vdmccom.tcl +++ b/mcstas/dmc/vdmccom.tcl @@ -6,7 +6,7 @@ source $home/mcsupport.tcl if { [info exists vdmcinit] == 0 } { - set vdmcinit 1f + set vdmcinit 1 Publish LogBook Spy Publish count User Publish Repeat User @@ -14,6 +14,7 @@ if { [info exists vdmcinit] == 0 } { Publish rundmcsim User Publish copydmcdata User Publish sample User + Publish wwwsics Spy mcinstall } source $home/log.tcl @@ -266,6 +267,11 @@ proc repeat { num {mode NULL} {preset NULL} } { } } } +#-------------------------------------------------------------------------- +proc GetNum { text } { + set list [split $text =] + return [lindex $list 1] +} #------------------------------------------------------------------------ # This implements the wwwsics command which generates a listing of # important experiment parameters in html format for the SICS WWW Status @@ -306,7 +312,70 @@ proc wwwsics {} { append result return $result } +#---------------------------------------------------------------------------- +# wwpar formats a parameter for display in the WWW-control. +# +# Mark Koennecke, June 2000 +#--------------------------------------------------------------------------- +set ret [catch {wwwpar motor a4} msg] +if {$ret != 0} { + Publish wwwpar Spy + Publish wwwuser Spy +} +#-------------------------------------------------------------------------- +proc WWWNum { text } { + set list [split $text =] + return [lindex $list 1] +} +#--------------------------------------------------------------------------- +proc wwwpar {type mot} { + append txt $mot , +#----- get lowerlimit, either from motor or temperature controller + if { [string compare $type motor] == 0} { + set ret [catch {$mot softlowerlim} msg] + } else { + set ret [catch {$mot lowerlimit} msg] + } + if {$ret != 0 } { + append txt UNKNOWN , + } else { + append txt [WWWNum $msg] , + } +#------- get value + set ret [catch {$mot} msg] + if {$ret == 0} { + append txt [WWWNum $msg] , + } else { + append txt UNKNOWN , + } +#----- get upperlimit, either from motor or temperature controller + if {[string compare $type motor] == 0} { + set ret [catch {$mot softupperlim} msg] + } else { + set ret [catch {$mot upperlimit} msg] + } + if {$ret != 0 } { + append txt UNKNOWN + } else { + append txt [WWWNum $msg] + } + return $txt +} +#------------- wwwuser formats user information into a html table +proc wwwuser {} { + lappend list title sample user email phone adress + append txt "" + foreach e $list { + set ret [catch {$e} msg] + if {$ret == 0} { + set l [split $msg =] + append txt "\n " + } + } + return $txt +} + -#------------ install command -catch {Publish wwwsics Spy} msg diff --git a/network.c b/network.c index 7aaab0f7..4cc86bcf 100644 --- a/network.c +++ b/network.c @@ -551,7 +551,7 @@ CreateSocketAdress( } } /*-------------------------------------------------------------------------*/ -int NETReadTillTermNew(mkChannel *self, long timeout, +int NETReadTillTerm(mkChannel *self, long timeout, char *pTerm, char *pBuffer, int iBufLen) { struct timeval start, now; @@ -576,7 +576,7 @@ int NETReadTillTermNew(mkChannel *self, long timeout, { return status; } - while (status > 0) + while (status > 0) { status = recv(self->sockid,&c,1,0); if(status <= 0) @@ -624,88 +624,6 @@ int NETReadTillTermNew(mkChannel *self, long timeout, assert(bufPtr > 0); return bufPtr; } -/*-------------------------------------------------------------------------- -This old version may be removed in some stage. It has two problems: - - The timeouts are not properly obeyed - - The code may read more data the it should, i.e. bytes after the - terminator of your hearts desire. - -------------------------------------------------------------------------*/ - int NETReadTillTerm(mkChannel *self, int timeout, - char *pTerm, char *pBuffer, int iBufLen) - { - int iRet, termLen, i, j, nLoop; - int read = 0; - - - if(!VerifyChannel(self)) - { - return -1; - } - - /* - how may cycles to read in order to have a timeout - */ - nLoop = timeout/5; - if(nLoop <= 0) - { - nLoop = 1; - } - - for(i = 0; i < nLoop; i++) - { - iRet = NETAvailable(self,5); - if(iRet < 0) - { - return iRet; - } - else if(iRet == 0) - { - continue; - } - else - { - /* - data is pending, read it - */ - iRet = recv(self->sockid,pBuffer+read,iBufLen - read,0); - if(iRet < 0) - { - return iRet; - } - else - { - read += iRet; - } - if(read >= iBufLen) - { - pBuffer[iBufLen-1] = '\0'; - } - else - { - pBuffer[read+1] = '\0'; - } - /* - have we found a terminator ? - */ - for(j = 0; j < strlen(pTerm); j++) - { - if(strrchr(pBuffer,pTerm[j]) != NULL) - { - return 1; - } - } - if(read >= iBufLen) - { - /* - we have filled the buffer but not found a terminator - */ - return -1; - } - } - } - return 0; /* timeout! */ - } - /*---------------------------------------------------------------------------*/ int NETClosePort(mkChannel *self) { diff --git a/network.h b/network.h index fbac7dc2..455d96f5 100644 --- a/network.h +++ b/network.h @@ -93,9 +93,7 @@ /* returns 1 if data is pending on the port, 0 if none is pending. */ - int NETReadTillTermNew(mkChannel *self, long timeout, - char *pTerm, char *pBuffer, int iBufLen); - int NETReadTillTerm(mkChannel *self, int timeout, + int NETReadTillTerm(mkChannel *self, long timeout, char *pTerm, char *pBuffer, int iBufLen); /* reads data until one of the terminators defined in pTerm has diff --git a/remob.c b/remob.c index 217a2675..fca5591e 100644 --- a/remob.c +++ b/remob.c @@ -101,7 +101,7 @@ static int RemRead(RemChannel *rc, long tmo) { int iRet; if (rc->chan == NULL) return 0; /* no data */ - iRet = NETReadTillTermNew(rc->chan, tmo, "\n", rc->line + rc->incomplete, + iRet = NETReadTillTerm(rc->chan, tmo, "\n", rc->line + rc->incomplete, sizeof(rc->line) - rc->incomplete); if (iRet == 0) { rc->incomplete = strlen(rc->line); /* number of chars already received */ diff --git a/rs232controller.c b/rs232controller.c index 1f4dcac8..17fe6509 100644 --- a/rs232controller.c +++ b/rs232controller.c @@ -216,7 +216,7 @@ int readRS232TillTerm(prs232 self, void *data, int *datalen){ memset(data,0,*datalen); replylen = *datalen; - iRet = NETReadTillTermNew(self->pSock,self->timeout,self->replyTerminator, + iRet = NETReadTillTerm(self->pSock,self->timeout,self->replyTerminator, (char *)data, replylen); if(self->debug > 0 && iRet > 0) { @@ -355,7 +355,7 @@ int transactRS232(prs232 self, void *send, int sendLen, read */ memset(reply,0,replyLen); - iRet = NETReadTillTermNew(self->pSock,self->timeout,self->replyTerminator, + iRet = NETReadTillTerm(self->pSock,self->timeout,self->replyTerminator, reply, replyLen); if(self->debug > 0) { diff --git a/tcl/sicstcldebug.tcl b/tcl/sicstcldebug.tcl index 0815f409..9f6e4856 100644 --- a/tcl/sicstcldebug.tcl +++ b/tcl/sicstcldebug.tcl @@ -23,6 +23,7 @@ proc unknown args { append com "transact " [join $args] puts $socke $com flush $socke + set reply "" while {1} { set line [gets $socke] if {[string first TRANSACTIONFINISHED $line] >= 0} {
" [lindex $l 0] " \n" + append txt "