- Conescan working now

- Removed old NETReadTillterm


SKIPPED:
	psi/libpsi.a
	psi/tasdriveo.c
This commit is contained in:
koennecke
2006-04-11 08:03:15 +00:00
parent da3dfd9d76
commit 38cfea4865
13 changed files with 230 additions and 124 deletions

37
cone.c
View File

@ -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 {

1
cone.h
View File

@ -19,6 +19,7 @@ typedef struct {
pIDrivable pDriv;
reflection target;
float lastConeAngle;
float qScale;
pUBCALC ubi;
int center;
pHKL pHkl;

5
cone.w
View File

@ -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.

77
doc/user/Conescan.html Normal file
View File

@ -0,0 +1,77 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html><head><title>Conescan.radi</title></head><body>
<h2>Conescan </h2>
<p>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:
</p></p><dl><dt>conescan list
<dd> lists all the parameters of the conescan
<dt>conescan cell
<dd> prints the cell constants.
<dt>conescan cell a b c alpha beta gamma
<dd> sets new cell constants.
<dt>conescan center
<dd> prints the current values for the center reflection
<dt>conescan center h k l
<dd> uses h, k, l as the indices of the center
reflection. Motor positions are read from motors.
<dt>conescan center h k l stt om chi phi
<dd> defines a center position
complete with all angles.
<dt>conescan target
<dd> prints the current target for the conescan
<dt>conescan target h k l
<dd> defines the target indices for the conescan.
<dt>conescan qscale
<dd> 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.
<dt>conescan qscale value
<dd> sets a new value for the qscale factor
<dt>conescan run step mode preset
<dd> starts a conescan with the nstep width
step, the couent mode mode and the preset preset.
<dt>conescan run
<dd> starts a conescan with defaults: step = .5,
mode = monitor, preset = 10000
<p></dl>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.
</p></p><h3>Implementation Reference </h3>
<p>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.
</p></p><p>The cone module does the actual cone calculation. Cone can be
configured with commands:
<dl></p><dt>cone center
<dd> prints the number of the reflection in ubcalc to use as
a center.
<dt>cone center num
<dd> 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.
<dt>cone target
<dd> prints the target reflection indices for the cone.
<dt>cone target h k l
<dd> sets the target reflection indices.
<dt>cone qscale
<dd> prints the current value of the scattering vector scale.
<dt>cone qscale val
<dd> sets a value for the scaling factor for the
scattering vector. Values should be close to 1.0;
</dl></body></html>

View File

@ -18,7 +18,7 @@ to be solved are:
<h3>Locate Reflections</h3>
<p>
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.
</p>
<p>
Once a peak has been found, its position can be optimised and centered with the
<a href="optimise.htm">peak optimiser</a>.
<a href="optimise.htm">peak optimiser</a>. Dor not forget to put all
collimators in and to close all slits before optimizing. This is in
order to improve accuracy.
</p>
<p>
Once one reflection has been located, others might be located using the
<a href="Conescan.html">conescan</a> method when the lattice constants
are known. Do not forget to open all slits and to remove all
collimators for this.
</p>
<p>
If two reflections and the cell constants are known, a provisional UB
matrix may be <a href="ubcalc.htm">calculated</a> with the UBCALC
module. UBCALC can also calculate the UB matrix from three reflections
from scratch.
</p>
<P>
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:
<DL>
<DT>rliste clear
<DD> clears all entries from the list

View File

@ -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

25
drive.c
View File

@ -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]);

View File

@ -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 </table>
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 "<table>"
foreach e $list {
set ret [catch {$e} msg]
if {$ret == 0} {
set l [split $msg =]
append txt "<tr><th>" [lindex $l 0] "</th><td> \n"
append txt "<INPUT type=text name=[lindex $l 0] value=\"[lindex $l 1]\" "
append txt "\n LENGTH=40 MAXLENGTH=80></td></tr>\n "
}
}
return $txt
}
#------------ install command
catch {Publish wwwsics Spy} msg

View File

@ -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;
@ -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)
{

View File

@ -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

View File

@ -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 */

View File

@ -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)
{

View File

@ -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} {