- Added file checking and listings to exeman

- Fixed some problems with mesure
- Fixed issues with tasub
This commit is contained in:
koennecke
2005-05-31 10:00:18 +00:00
parent 6006f20101
commit f33ca7b0d7
10 changed files with 354 additions and 30 deletions

201
exeman.c
View File

@ -11,6 +11,8 @@
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include <tcl.h> #include <tcl.h>
#include <dirent.h>
#include <ctype.h>
#include "fortify.h" #include "fortify.h"
#include "sics.h" #include "sics.h"
#include "exebuf.h" #include "exebuf.h"
@ -388,6 +390,45 @@ static int appendLine(pExeMan self, SConnection *pCon,
return 1; return 1;
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static int uploadForceSave(pExeMan self, SConnection *pCon,
int argc, char *argv[]){
int status;
char pPath[256], *pPtr;
if(SCGetRights(pCon) > usUser){
SCWrite(pCon,"ERROR: no permission to save buffers",eError);
return 0;
}
if(argc < 3) {
SCWrite(pCon,"ERROR: no file given to save upload buffer to",eError);
return 0;
}
if(self->uploadBuffer == NULL){
SCWrite(pCon,"ERROR: no upload buffer to save exists",eError);
return 0;
}
if(argv[2][0] != '/') {
pPtr = self->batchPath;
pPtr = stptok(pPtr,pPath,131,":");
if(strlen(pPath) + 1 + strlen(argv[2]) <= 256){
strcat(pPath,"/");
strcat(pPath,argv[2]);
} else {
strncpy(pPath,argv[2],255);
}
} else {
strncpy(pPath,argv[2],131);
}
status = exeBufSave(self->uploadBuffer,pPath);
if(status == 0){
SCWrite(pCon,"ERROR: failed to save exe buffer, destroyed...",eError);
}
exeBufDelete(self->uploadBuffer);
self->uploadBuffer = NULL;
return status;
}
/*--------------------------------------------------------------------*/
static int uploadSave(pExeMan self, SConnection *pCon, static int uploadSave(pExeMan self, SConnection *pCon,
int argc, char *argv[]){ int argc, char *argv[]){
int status; int status;
@ -417,6 +458,11 @@ static int uploadSave(pExeMan self, SConnection *pCon,
} else { } else {
strncpy(pPath,argv[2],131); strncpy(pPath,argv[2],131);
} }
if(fileExists(pPath)) {
SCWrite(pCon,"ERROR: file exists",eError);
return 0;
}
status = exeBufSave(self->uploadBuffer,pPath); status = exeBufSave(self->uploadBuffer,pPath);
if(status == 0){ if(status == 0){
SCWrite(pCon,"ERROR: failed to save exe buffer, destroyed...",eError); SCWrite(pCon,"ERROR: failed to save exe buffer, destroyed...",eError);
@ -425,6 +471,141 @@ static int uploadSave(pExeMan self, SConnection *pCon,
self->uploadBuffer = NULL; self->uploadBuffer = NULL;
return status; return status;
} }
/*---------------------------------------------------------------------------------*/
/* See if a string matches a wildcard specification that uses * or ?
(like "*.txt"), and return TRUE or FALSE, depending on the result.
There's also a TRUE/FALSE parameter you use to indicate whether
the match should be case-sensitive or not.
*/
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/*--------------------------------------------------------------------------------*/
static int IsWildcardMatch (char *wildcardString, char *stringToCheck, int caseSensitive)
{
char wcChar;
char strChar;
// use the starMatchesZero variable to determine whether an asterisk
// matches zero or more characters (TRUE) or one or more characters
// (FALSE)
int starMatchesZero = TRUE;
while ((strChar = *stringToCheck) && (wcChar = *wildcardString))
{
// we only want to advance the pointers if we successfully assigned
// both of our char variables, so we'll do it here rather than in the
// loop condition itself
*stringToCheck++;
*wildcardString++;
// if this isn't a case-sensitive match, make both chars uppercase
// (thanks to David John Fielder (Konan) at http://innuendo.ev.ca
// for pointing out an error here in the original code)
if (!caseSensitive)
{
wcChar = toupper(wcChar);
strChar = toupper(strChar);
}
// check the wcChar against our wildcard list
switch (wcChar)
{
// an asterisk matches zero or more characters
case '*' :
// do a recursive call against the rest of the string,
// until we've either found a match or the string has
// ended
if (starMatchesZero)
*stringToCheck--;
while (*stringToCheck)
{
if (IsWildcardMatch(wildcardString, stringToCheck++, caseSensitive))
return TRUE;
}
break;
// a question mark matches any single character
case '?' :
break;
// if we fell through, we want an exact match
default :
if (wcChar != strChar)
return FALSE;
break;
}
}
// if we have any asterisks left at the end of the wildcard string, we can
// advance past them if starMatchesZero is TRUE (so "blah*" will match "blah")
while ((*wildcardString) && (starMatchesZero))
{
if (*wildcardString == '*')
wildcardString++;
else
break;
}
// if we got to the end but there's still stuff left in either of our strings,
// return false; otherwise, we have a match
if ((*stringToCheck) || (*wildcardString))
return FALSE;
else
return TRUE;
}
/*----------------------------------------------------------------------------*/
static int wwmatch(char *pattern, char *name){
return IsWildcardMatch(pattern,name,1);
}
/*--------------------------------------------------------------------
search the directory pPath for file matching pattern. Successfull
files will be appended to result
-----------------------------------------------------------------------*/
static void searchDir(char *pPath, char *pattern, pDynString result){
DIR *currentdir = NULL;
struct dirent *currentFile = NULL;
currentdir = opendir(pPath);
if(currentdir == NULL){
return;
}
currentFile = readdir(currentdir);
while(currentFile != NULL){
if(wwmatch((const char *)pattern, currentFile->d_name)){
DynStringConcat(result,currentFile->d_name);
DynStringConcatChar(result,'\n');
}
currentFile = readdir(currentdir);
}
closedir(currentdir);
}
/*--------------------------------------------------------------------*/
static pDynString findDirEntries(pExeMan self, char *pattern){
pDynString result = NULL;
char pPath[132], *pPtr = NULL;
result = CreateDynString(256,256);
if(!result){
return NULL;
}
pPtr = self->batchPath;
while((pPtr = stptok(pPtr,pPath,131,":")) != NULL){
searchDir(pPath,pattern,result);
}
pPtr = self->sysPath;
while((pPtr = stptok(pPtr,pPath,131,":")) != NULL){
searchDir(pPath,pattern,result);
}
return result;
}
/*=========================== info ===================================*/ /*=========================== info ===================================*/
static void printExeStack(pExeMan self, SConnection *pCon){ static void printExeStack(pExeMan self, SConnection *pCon){
int i, j; int i, j;
@ -730,6 +911,7 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
pExeMan self = NULL; pExeMan self = NULL;
char pBufferName[256]; char pBufferName[256];
int status; int status;
pDynString dirList = NULL;
self = (pExeMan)pData; self = (pExeMan)pData;
assert(self != NULL); assert(self != NULL);
@ -768,6 +950,12 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
SCSendOK(pCon); SCSendOK(pCon);
} }
return status; return status;
}else if(strcmp(argv[1],"forcesave") == 0){
status = uploadForceSave(self,pCon,argc,argv);
if(status){
SCSendOK(pCon);
}
return status;
}else if(strcmp(argv[1],"info") == 0){ }else if(strcmp(argv[1],"info") == 0){
status = infoHandler(self,pCon,argc,argv); status = infoHandler(self,pCon,argc,argv);
return status; return status;
@ -780,6 +968,19 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
SCSendOK(pCon); SCSendOK(pCon);
} }
return status; return status;
} else if(strcmp(argv[1],"dir") == 0){
if(argc <= 2){
dirList = findDirEntries(self,"*");
} else {
dirList = findDirEntries(self,argv[2]);
}
if(dirList != NULL){
SCWrite(pCon,GetCharArray(dirList),eValue);
DeleteDynString(dirList);
} else {
SCWrite(pCon,"Nothing found",eValue);
}
return 1;
}else if(strcmp(argv[1],"clear") == 0){ }else if(strcmp(argv[1],"clear") == 0){
clearQueue(self); clearQueue(self);
SCSendOK(pCon); SCSendOK(pCon);

View File

@ -39,6 +39,7 @@ static void clearTable(int handle){
LLDnodeDelete(handle); LLDnodeDelete(handle);
status = LLDnodePtr2Next(handle); status = LLDnodePtr2Next(handle);
} }
LLDnodeDelete(handle);
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
static void printList(int handle, SConnection *pCon){ static void printList(int handle, SConnection *pCon){
@ -240,17 +241,15 @@ int HandleFourCircleCommands(int handle, SConnection *pCon,
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static FourTableEntry findEntry(int handle, double two_theta){ static FourTableEntry findEntry(int handle, double two_theta){
int status; int status;
FourTableEntry entry, prevEntry; FourTableEntry entry;
status = LLDnodePtr2First(handle); status = LLDnodePtr2First(handle);
LLDnodeDataTo(handle,&prevEntry);
while(status == 1) { while(status == 1) {
LLDnodeDataTo(handle,&entry); LLDnodeDataTo(handle,&entry);
if(entry.twoThetaEnd > two_theta){ if(entry.twoThetaEnd > two_theta){
return prevEntry; return entry;
} }
status = LLDnodePtr2Next(handle); status = LLDnodePtr2Next(handle);
prevEntry = entry;
} }
strcpy(entry.scanVar,"NOT FOUND"); strcpy(entry.scanVar,"NOT FOUND");
return entry; return entry;

View File

@ -53,7 +53,9 @@
pHKL pCryst; /* hkl object for crystallographic calc pHKL pCryst; /* hkl object for crystallographic calc
and reflection driving */ and reflection driving */
pMotor pOmega; /* motor for omega scans */ pMotor pOmega; /* motor for omega scans */
pMotor p2Theta; /* motor for 2 theta scans*/
char *pCOmega; /* name of omega motor */ char *pCOmega; /* name of omega motor */
char *pC2Theta; /* name of 2 theta motor */
char *pFileRoot; /* where to write files */ char *pFileRoot; /* where to write files */
pDataNumber pDanu; /* where to get data file number */ pDataNumber pDanu; /* where to get data file number */
FILE *fRefl; /* reflection profile file */ FILE *fRefl; /* reflection profile file */
@ -140,7 +142,8 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
pMesure CreateMesure(pHKL pCryst, pScanData pScanner, pMotor pOmega, pMesure CreateMesure(pHKL pCryst, pScanData pScanner, pMotor pOmega,
char *pOm, char *pFileRoot, char *pOm, pMotor p2Theta, char *p2t,
char *pFileRoot,
pDataNumber pDanu) pDataNumber pDanu)
{ {
pMesure pNew = NULL; pMesure pNew = NULL;
@ -172,7 +175,9 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
pNew->pScanner = pScanner; pNew->pScanner = pScanner;
pNew->pCryst = pCryst; pNew->pCryst = pCryst;
pNew->pOmega = pOmega; pNew->pOmega = pOmega;
pNew->p2Theta = p2Theta;
pNew->pCOmega = strdup(pOm); pNew->pCOmega = strdup(pOm);
pNew->pC2Theta = strdup(p2t);
pNew->pFileRoot = strdup(pFileRoot); pNew->pFileRoot = strdup(pFileRoot);
pNew->pDanu = pDanu; pNew->pDanu = pDanu;
pNew->iCount = 0; pNew->iCount = 0;
@ -229,7 +234,7 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
pHKL pCryst = NULL; pHKL pCryst = NULL;
pScanData pScan = NULL; pScanData pScan = NULL;
CommandList *pCom = NULL; CommandList *pCom = NULL;
pMotor pMot = NULL; pMotor pMot = NULL, pMot2 = NULL;
pDataNumber pDanu = NULL; pDataNumber pDanu = NULL;
pSicsO2T pO2T = NULL; pSicsO2T pO2T = NULL;
char pBueffel[512]; char pBueffel[512];
@ -242,7 +247,7 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
/* check no of parameters /* check no of parameters
inicom name hkl scan omega root danu inicom name hkl scan omega root danu
*/ */
if(argc < 7) if(argc < 8)
{ {
SCWrite(pCon, SCWrite(pCon,
"ERROR: Insufficient number of parameters to MesureFactory",eError); "ERROR: Insufficient number of parameters to MesureFactory",eError);
@ -298,8 +303,17 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
return 0; return 0;
} }
/* 2 theta */
pMot2 = FindMotor(pSics,argv[5]);
if(!pMot2)
{
sprintf(pBueffel,"ERROR: %s is no motor object ",argv[5]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* Data Number */ /* Data Number */
pCom = FindCommand(pSics,argv[6]); pCom = FindCommand(pSics,argv[7]);
if(pCom) if(pCom)
{ {
pDum = (pDummy)pCom->pData; pDum = (pDummy)pCom->pData;
@ -313,13 +327,14 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
} }
if(!pDanu) if(!pDanu)
{ {
sprintf(pBueffel,"ERROR: %s is no DataNumber object",argv[6]); sprintf(pBueffel,"ERROR: %s is no DataNumber object",argv[7]);
SCWrite(pCon,pBueffel,eError); SCWrite(pCon,pBueffel,eError);
return 0; return 0;
} }
/* finally create the thing */ /* finally create the thing */
pNew = CreateMesure(pCryst,pScan,pMot,argv[4],argv[5],pDanu); pNew = CreateMesure(pCryst,pScan,pMot,argv[4], pMot2, argv[5],
argv[6],pDanu);
if(!pNew) if(!pNew)
{ {
SCWrite(pCon,"ERROR: no memory in MesureFactory",eError); SCWrite(pCon,"ERROR: no memory in MesureFactory",eError);
@ -415,7 +430,7 @@ static int getMesureNP(pMesure self, double twoTheta)
This is supposed to be automatically set. In order to do so, I need This is supposed to be automatically set. In order to do so, I need
the step width which in turn is dependent on two theta. Therefore I calculate the step width which in turn is dependent on two theta. Therefore I calculate
two times: the first time with a scan tolerance of 0 to get two theta, the two times: the first time with a scan tolerance of 0 to get two theta, the
second time with teh scan tolerance ste to a decent value to get the second time with the scan tolerance ste to a decent value to get the
real thing. real thing.
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
static int MesureCalculateSettings(pMesure self, float fHKL[3], float fSet[4], static int MesureCalculateSettings(pMesure self, float fHKL[3], float fSet[4],
@ -611,13 +626,29 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
/* /*
below is the code for a single counter scan. below is the code for a single counter scan.
TODO: (maybe) make this clearer and separte this into another subroutine TODO: (maybe) make this clearer and separate this into another subroutine
Set the scan up Set the scan up
*/ */
ClearScanVar(self->pScanner); ClearScanVar(self->pScanner);
AddScanVar(self->pScanner, pServ->pSics,pCon,scanVar, AddScanVar(self->pScanner, pServ->pSics,pCon,self->pCOmega,
fStart, stepWidth); fStart, stepWidth);
/*
Oksana does not want o2t scans to be tightly coupled, this is why we
cannot use the normal o2t scan variable. Instead we calculate new limits and
steps for 2 theta and use it as a second scan variable
*/
if(strstr(scanVar,"o2t") != NULL){
iRet = MotorGetSoftPosition(self->p2Theta,pCon,&fStart);
if(!iRet)
{
return iRet;
}
stepWidth *= 2.;
fStart -= (np/2.)*stepWidth;
AddScanVar(self->pScanner, pServ->pSics,pCon,self->pC2Theta,
fStart, stepWidth);
}
/* /*
as np can change, we have to reallocate enough space as np can change, we have to reallocate enough space

View File

@ -17,6 +17,7 @@
/*--------------------- live & death --------------------------------------*/ /*--------------------- live & death --------------------------------------*/
pMesure CreateMesure(pHKL pCryst, pScanData pScanner, pMesure CreateMesure(pHKL pCryst, pScanData pScanner,
pMotor pOmega, char *pom, pMotor pOmega, char *pom,
pMotor p2Theta, char *p2t,
char *pFileRoot,pDataNumber pDanu); char *pFileRoot,pDataNumber pDanu);
void DeleteMesure(void *pData); void DeleteMesure(void *pData);

View File

@ -25,6 +25,7 @@ The interface to this object consists of these functions:
/*--------------------- live & death --------------------------------------*/ /*--------------------- live & death --------------------------------------*/
pMesure CreateMesure(pHKL pCryst, pScanData pScanner, pMesure CreateMesure(pHKL pCryst, pScanData pScanner,
pMotor pOmega, char *pom, pMotor pOmega, char *pom,
pMotor p2Theta, char *p2t,
char *pFileRoot,pDataNumber pDanu); char *pFileRoot,pDataNumber pDanu);
void DeleteMesure(void *pData); void DeleteMesure(void *pData);

View File

@ -732,7 +732,7 @@ extern void KillPiPiezo(void *pData);
iRet = MotorCheckBoundary(self,fNew,&fHard,pBueffel,511); iRet = MotorCheckBoundary(self,fNew,&fHard,pBueffel,511);
if(!iRet) if(!iRet)
{ {
SCWrite(pCon,pBueffel,eStatus); SCWrite(pCon,pBueffel,eWarning);
SCSetInterrupt(pCon,eAbortOperation); SCSetInterrupt(pCon,eAbortOperation);
return 0; return 0;
} }

73
nxxml.h Normal file
View File

@ -0,0 +1,73 @@
/*
* This is the header file for the NeXus XML file driver.
*
* Copyright (C) 2004 Mark Koennecke
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For further information, see <http://www.neutron.anl.gov/NeXus/>
*/
#ifndef NEXUSXML
#define NEXUSXML
NX_EXTERNAL NXstatus CALLING_STYLE NXXopen(CONSTCHAR *filename, NXaccess access_method, NXhandle* pHandle);
NX_EXTERNAL NXstatus CALLING_STYLE NXXclose(NXhandle* pHandle);
NX_EXTERNAL NXstatus CALLING_STYLE NXXflush(NXhandle* pHandle);
NXstatus CALLING_STYLE NXXmakegroup (NXhandle fid, CONSTCHAR *name,
CONSTCHAR *nxclass);
NXstatus CALLING_STYLE NXXopengroup (NXhandle fid, CONSTCHAR *name,
CONSTCHAR *nxclass);
NXstatus CALLING_STYLE NXXclosegroup (NXhandle fid);
NXstatus CALLING_STYLE NXXcompmakedata (NXhandle fid, CONSTCHAR *name,
int datatype,
int rank,
int dimensions[],
int compress_type, int chunk_size[]);
NXstatus CALLING_STYLE NXXmakedata (NXhandle fid,
CONSTCHAR *name, int datatype,
int rank, int dimensions[]);
NXstatus CALLING_STYLE NXXopendata (NXhandle fid, CONSTCHAR *name);
NXstatus CALLING_STYLE NXXclosedata (NXhandle fid);
NXstatus CALLING_STYLE NXXputdata (NXhandle fid, void *data);
NXstatus CALLING_STYLE NXXgetdata (NXhandle fid, void *data);
NXstatus CALLING_STYLE NXXgetinfo (NXhandle fid, int *rank,
int dimension[], int *iType);
NXstatus CALLING_STYLE NXXputslab (NXhandle fid, void *data,
int iStart[], int iSize[]);
NXstatus CALLING_STYLE NXXgetslab (NXhandle fid, void *data,
int iStart[], int iSize[]);
NXstatus CALLING_STYLE NXXputattr (NXhandle fid, CONSTCHAR *name, void *data,
int datalen, int iType);
NXstatus CALLING_STYLE NXXgetattr (NXhandle fid, char *name,
void *data, int* datalen, int* iType);
NXstatus CALLING_STYLE NXXgetnextentry (NXhandle fid,NXname name,
NXname nxclass, int *datatype);
NX_EXTERNAL NXstatus CALLING_STYLE NXXgetnextattr(NXhandle handle,
NXname pName, int *iLength, int *iType);
NX_EXTERNAL NXstatus CALLING_STYLE NXXinitgroupdir(NXhandle handle);
NX_EXTERNAL NXstatus CALLING_STYLE NXXinitattrdir(NXhandle handle);
NX_EXTERNAL NXstatus CALLING_STYLE NXXgetattrinfo (NXhandle fid, int *iN);
NX_EXTERNAL NXstatus CALLING_STYLE NXXgetgroupinfo (NXhandle fid, int *iN,
NXname pName, NXname pClass);
NX_EXTERNAL NXstatus CALLING_STYLE NXXgetdataID (NXhandle fid, NXlink* sRes);
NX_EXTERNAL NXstatus CALLING_STYLE NXXgetgroupID (NXhandle fid, NXlink* sRes);
NX_EXTERNAL NXstatus CALLING_STYLE NXXmakelink (NXhandle fid, NXlink* sLink);
NX_EXTERNAL NXstatus CALLING_STYLE NXXsameID (NXhandle fileid,
NXlink* pFirstID, NXlink* pSecondID);
#endif

View File

@ -329,19 +329,23 @@ static int calculateAndDrive(ptasMot self, SConnection *pCon){
switch(status){ switch(status){
case ENERGYTOBIG: case ENERGYTOBIG:
SCWrite(pCon,"ERROR: desired energy to big",eError); SCWrite(pCon,"ERROR: desired energy to big",eError);
self->math->mustDrive = 0;
return HWFault; return HWFault;
break; break;
case UBNOMEMORY: case UBNOMEMORY:
SCWrite(pCon,"ERROR: out of memory calculating angles",eError); SCWrite(pCon,"ERROR: out of memory calculating angles",eError);
self->math->mustDrive = 0;
return HWFault; return HWFault;
break; break;
case BADRMATRIX: case BADRMATRIX:
SCWrite(pCon,"ERROR: bad crystallographic parameters or bad UB",eError); SCWrite(pCon,"ERROR: bad crystallographic parameters or bad UB",eError);
self->math->mustDrive = 0;
return HWFault; return HWFault;
break; break;
case TRIANGLENOTCLOSED: case TRIANGLENOTCLOSED:
SCWrite(pCon,"ERROR: cannot close scattering triangle",eError); SCWrite(pCon,"ERROR: cannot close scattering triangle",eError);
self->math->mustDrive = 0;
return HWFault; return HWFault;
break; break;
default: default:

33
tasub.c
View File

@ -490,7 +490,7 @@ static void listReflections(ptasUB self, SConnection *pCon){
Tcl_DStringInit(&list); Tcl_DStringInit(&list);
snprintf(line,255, snprintf(line,255,
" NO QH QK QL A3 A4 SGU SGL KI KF\n"); " NO QH QK QL A3 A4 SGU SGL EI EF\n");
Tcl_DStringAppend(&list,line,-1); Tcl_DStringAppend(&list,line,-1);
status = LLDnodePtr2First(self->reflectionList); status = LLDnodePtr2First(self->reflectionList);
while(status == 1){ while(status == 1){
@ -498,7 +498,7 @@ static void listReflections(ptasUB self, SConnection *pCon){
LLDnodeDataTo(self->reflectionList,&r); LLDnodeDataTo(self->reflectionList,&r);
snprintf(line,255,"%3d %6.2f %6.2f %6.2f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n", snprintf(line,255,"%3d %6.2f %6.2f %6.2f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n",
count, r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3, r.angles.sample_two_theta, count, r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3, r.angles.sample_two_theta,
r.angles.sgu, r.angles.sgl, r.qe.ki, r.qe.kf); r.angles.sgu, r.angles.sgl, KtoEnergy(r.qe.ki), KtoEnergy(r.qe.kf));
Tcl_DStringAppend(&list,line,-1); Tcl_DStringAppend(&list,line,-1);
status = LLDnodePtr2Next(self->reflectionList); status = LLDnodePtr2Next(self->reflectionList);
} }
@ -510,6 +510,8 @@ static void listReflections(ptasUB self, SConnection *pCon){
Tcl_DStringFree(&list); Tcl_DStringFree(&list);
} }
/*-------------------------------------------------------------------*/ /*-------------------------------------------------------------------*/
#define ABS(x) (x < 0 ? -(x) : (x))
/*-------------------------------------------------------------------*/
static int addReflection(ptasUB self, SicsInterp *pSics, static int addReflection(ptasUB self, SicsInterp *pSics,
SConnection *pCon, SConnection *pCon,
int argc, char *argv[]){ int argc, char *argv[]){
@ -597,18 +599,22 @@ static int addReflection(ptasUB self, SicsInterp *pSics,
if(status != 1){ if(status != 1){
return status; return status;
} }
r.qe.ki = maCalcK(self->machine.monochromator,angles.monochromator_two_theta); r.qe.ki = maCalcK(self->machine.monochromator,r.angles.monochromator_two_theta);
r.qe.kf = maCalcK(self->machine.analyzer,angles.analyzer_two_theta); r.qe.kf = maCalcK(self->machine.analyzer,r.angles.analyzer_two_theta);
}
if(ABS(r.qe.ki - r.qe.kf) > .01) {
SCWrite(pCon,"WARNING: KI != KF!",eWarning);
} }
LLDnodeAppend(self->reflectionList,&r); LLDnodeAppend(self->reflectionList,&r);
Tcl_DStringInit(&list); Tcl_DStringInit(&list);
snprintf(pBueffel,255, snprintf(pBueffel,255,
" QH QK QL A3 A4 SGU SGL KI KF\n"); " QH QK QL A3 A4 SGU SGL EI EF\n");
Tcl_DStringAppend(&list,pBueffel,-1); Tcl_DStringAppend(&list,pBueffel,-1);
snprintf(pBueffel,255, snprintf(pBueffel,255,
" %6.2f %6.2f %6.2f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n", " %6.2f %6.2f %6.2f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n",
r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3, r.angles.sample_two_theta, r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3, r.angles.sample_two_theta,
r.angles.sgu, r.angles.sgl, r.qe.ki, r.qe.kf); r.angles.sgu, r.angles.sgl, KtoEnergy(r.qe.ki),
KtoEnergy(r.qe.kf));
Tcl_DStringAppend(&list,pBueffel,-1); Tcl_DStringAppend(&list,pBueffel,-1);
SCWrite(pCon,Tcl_DStringValue(&list),eValue); SCWrite(pCon,Tcl_DStringValue(&list),eValue);
Tcl_DStringFree(&list); Tcl_DStringFree(&list);
@ -669,12 +675,13 @@ static void printReflectionDiagnostik(ptasUB self, SConnection *pCon,
Tcl_DStringInit(&list); Tcl_DStringInit(&list);
snprintf(line,255, snprintf(line,255,
"METHOD QH QK QL A3 A4 SGU SGL KI KF\n"); "METHOD QH QK QL A3 A4 SGU SGL EI EF\n");
Tcl_DStringAppend(&list,line,-1); Tcl_DStringAppend(&list,line,-1);
snprintf(line,255, snprintf(line,255,
"INPUT %6.2f %6.2f %6.2f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n", "INPUT %8.4f %8.4f %8.4f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n",
r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3, r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3,
r.angles.sample_two_theta, r.angles.sgu, r.angles.sgl, r.qe.ki, r.qe.kf); r.angles.sample_two_theta, r.angles.sgu, r.angles.sgl,
KtoEnergy(r.qe.ki), KtoEnergy(r.qe.kf));
Tcl_DStringAppend(&list,line,-1); Tcl_DStringAppend(&list,line,-1);
qe.ki = r.qe.ki; qe.ki = r.qe.ki;
qe.kf = r.qe.kf; qe.kf = r.qe.kf;
@ -683,10 +690,10 @@ static void printReflectionDiagnostik(ptasUB self, SConnection *pCon,
qe.ql = r.qe.ql; qe.ql = r.qe.ql;
calcAllTasAngles(&self->machine,qe,&angles); calcAllTasAngles(&self->machine,qe,&angles);
snprintf(line,255, snprintf(line,255,
"QE->ANG %6.2f %6.2f %6.2f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n", "QE->ANG %8.4f %8.4f %8.4f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n",
r.qe.qh, r.qe.qk, r.qe.ql, r.qe.qh, r.qe.qk, r.qe.ql,
angles.a3, angles.sample_two_theta, angles.a3, angles.sample_two_theta,
angles.sgu, angles.sgl, r.qe.ki, r.qe.kf); angles.sgu, angles.sgl, KtoEnergy(r.qe.ki), KtoEnergy(r.qe.kf));
Tcl_DStringAppend(&list,line,-1); Tcl_DStringAppend(&list,line,-1);
angles.a3 = r.angles.a3; angles.a3 = r.angles.a3;
angles.sample_two_theta = r.angles.sample_two_theta; angles.sample_two_theta = r.angles.sample_two_theta;
@ -694,9 +701,9 @@ static void printReflectionDiagnostik(ptasUB self, SConnection *pCon,
angles.sgl = r.angles.sgl; angles.sgl = r.angles.sgl;
calcTasQEPosition(&self->machine,angles,&qe); calcTasQEPosition(&self->machine,angles,&qe);
snprintf(line,255, snprintf(line,255,
"ANG->QE %6.2f %6.2f %6.2f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n", "ANG->QE %8.4f %8.4f %8.4f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n",
qe.qh, qe.qk, qe.ql, angles.a3, angles.sample_two_theta, qe.qh, qe.qk, qe.ql, angles.a3, angles.sample_two_theta,
angles.sgu, angles.sgl, qe.ki, qe.kf); angles.sgu, angles.sgl, KtoEnergy(qe.ki), KtoEnergy(qe.kf));
Tcl_DStringAppend(&list,line,-1); Tcl_DStringAppend(&list,line,-1);
SCWrite(pCon,Tcl_DStringValue(&list),eWarning); SCWrite(pCon,Tcl_DStringValue(&list),eWarning);
Tcl_DStringFree(&list); Tcl_DStringFree(&list);

View File

@ -260,7 +260,9 @@ static MATRIX buildTVMatrix(MATRIX U1V, MATRIX U2V){
MATRIX T, T3V; MATRIX T, T3V;
int i; int i;
normalizeVector(U2V);
T3V = vectorCrossProduct(U1V,U2V); T3V = vectorCrossProduct(U1V,U2V);
normalizeVector(T3V);
if(T3V == NULL){ if(T3V == NULL){
return NULL; return NULL;
} }
@ -340,12 +342,17 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe,
} }
om = Acosd(R[0][0]/sq); om = Acosd(R[0][0]/sq);
om -= 180.; om -= 180.;
angles->sgl = Acosd(sqrt(R[0][0]*R[0][0] + R[1][0]*R[1][0])); tmp = Asind(R[1][0]/sqrt(R[0][0]*R[0][0] + R[1][0]*R[1][0]));
tmp = Acosd(sqrt(R[0][0]*R[0][0] + R[1][0]*R[1][0]));
angles->sgl = Asind(-R[2][0]);
sq = sqrt(R[0][0]*R[0][0] + R[1][0]*R[1][0]); sq = sqrt(R[0][0]*R[0][0] + R[1][0]*R[1][0]);
if(ABS(sq) < .00001){ if(ABS(sq) < .00001){
return BADRMATRIX; return BADRMATRIX;
} }
angles->sgu = Asind(R[2][1]/sq); angles->sgu = Asind(R[2][1]/sq);
tmp = Acosd(R[2][2]/sqrt(R[0][0]*R[0][0]+R[1][0]*R[1][0]));
QC = tasReflectionToQC(qe,UB); QC = tasReflectionToQC(qe,UB);
if(QC == NULL){ if(QC == NULL){
@ -355,7 +362,7 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe,
q = vectorLength(QC); q = vectorLength(QC);
q = 2.*PI*vectorLength(QC); q = 2.*PI*vectorLength(QC);
cos2t = (qe.ki*qe.ki + qe.kf*qe.kf - q*q)/(2. * ABS(qe.ki) * ABS(qe.kf)); cos2t = (qe.ki*qe.ki + qe.kf*qe.kf - q*q)/(2. * ABS(qe.ki) * ABS(qe.kf));
if(cos2t > 1.){ if(ABS(cos2t) > 1.){
return TRIANGLENOTCLOSED; return TRIANGLENOTCLOSED;
} }
angles->sample_two_theta = ss*Acosd(cos2t); angles->sample_two_theta = ss*Acosd(cos2t);