- Added file checking and listings to exeman
- Fixed some problems with mesure - Fixed issues with tasub
This commit is contained in:
201
exeman.c
201
exeman.c
@ -11,6 +11,8 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <tcl.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "exebuf.h"
|
||||
@ -388,6 +390,45 @@ static int appendLine(pExeMan self, SConnection *pCon,
|
||||
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,
|
||||
int argc, char *argv[]){
|
||||
int status;
|
||||
@ -417,6 +458,11 @@ static int uploadSave(pExeMan self, SConnection *pCon,
|
||||
} else {
|
||||
strncpy(pPath,argv[2],131);
|
||||
}
|
||||
if(fileExists(pPath)) {
|
||||
SCWrite(pCon,"ERROR: file exists",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = exeBufSave(self->uploadBuffer,pPath);
|
||||
if(status == 0){
|
||||
SCWrite(pCon,"ERROR: failed to save exe buffer, destroyed...",eError);
|
||||
@ -425,6 +471,141 @@ static int uploadSave(pExeMan self, SConnection *pCon,
|
||||
self->uploadBuffer = NULL;
|
||||
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 ===================================*/
|
||||
static void printExeStack(pExeMan self, SConnection *pCon){
|
||||
int i, j;
|
||||
@ -730,6 +911,7 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
pExeMan self = NULL;
|
||||
char pBufferName[256];
|
||||
int status;
|
||||
pDynString dirList = NULL;
|
||||
|
||||
self = (pExeMan)pData;
|
||||
assert(self != NULL);
|
||||
@ -768,6 +950,12 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
SCSendOK(pCon);
|
||||
}
|
||||
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){
|
||||
status = infoHandler(self,pCon,argc,argv);
|
||||
return status;
|
||||
@ -780,6 +968,19 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
SCSendOK(pCon);
|
||||
}
|
||||
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){
|
||||
clearQueue(self);
|
||||
SCSendOK(pCon);
|
||||
|
@ -39,6 +39,7 @@ static void clearTable(int handle){
|
||||
LLDnodeDelete(handle);
|
||||
status = LLDnodePtr2Next(handle);
|
||||
}
|
||||
LLDnodeDelete(handle);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
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){
|
||||
int status;
|
||||
FourTableEntry entry, prevEntry;
|
||||
FourTableEntry entry;
|
||||
|
||||
status = LLDnodePtr2First(handle);
|
||||
LLDnodeDataTo(handle,&prevEntry);
|
||||
while(status == 1) {
|
||||
LLDnodeDataTo(handle,&entry);
|
||||
if(entry.twoThetaEnd > two_theta){
|
||||
return prevEntry;
|
||||
return entry;
|
||||
}
|
||||
status = LLDnodePtr2Next(handle);
|
||||
prevEntry = entry;
|
||||
}
|
||||
strcpy(entry.scanVar,"NOT FOUND");
|
||||
return entry;
|
||||
|
49
mesure.c
49
mesure.c
@ -53,7 +53,9 @@
|
||||
pHKL pCryst; /* hkl object for crystallographic calc
|
||||
and reflection driving */
|
||||
pMotor pOmega; /* motor for omega scans */
|
||||
pMotor p2Theta; /* motor for 2 theta scans*/
|
||||
char *pCOmega; /* name of omega motor */
|
||||
char *pC2Theta; /* name of 2 theta motor */
|
||||
char *pFileRoot; /* where to write files */
|
||||
pDataNumber pDanu; /* where to get data file number */
|
||||
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,
|
||||
char *pOm, char *pFileRoot,
|
||||
char *pOm, pMotor p2Theta, char *p2t,
|
||||
char *pFileRoot,
|
||||
pDataNumber pDanu)
|
||||
{
|
||||
pMesure pNew = NULL;
|
||||
@ -172,7 +175,9 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
|
||||
pNew->pScanner = pScanner;
|
||||
pNew->pCryst = pCryst;
|
||||
pNew->pOmega = pOmega;
|
||||
pNew->p2Theta = p2Theta;
|
||||
pNew->pCOmega = strdup(pOm);
|
||||
pNew->pC2Theta = strdup(p2t);
|
||||
pNew->pFileRoot = strdup(pFileRoot);
|
||||
pNew->pDanu = pDanu;
|
||||
pNew->iCount = 0;
|
||||
@ -229,7 +234,7 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
|
||||
pHKL pCryst = NULL;
|
||||
pScanData pScan = NULL;
|
||||
CommandList *pCom = NULL;
|
||||
pMotor pMot = NULL;
|
||||
pMotor pMot = NULL, pMot2 = NULL;
|
||||
pDataNumber pDanu = NULL;
|
||||
pSicsO2T pO2T = NULL;
|
||||
char pBueffel[512];
|
||||
@ -242,7 +247,7 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
|
||||
/* check no of parameters
|
||||
inicom name hkl scan omega root danu
|
||||
*/
|
||||
if(argc < 7)
|
||||
if(argc < 8)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: Insufficient number of parameters to MesureFactory",eError);
|
||||
@ -298,8 +303,17 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
|
||||
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 */
|
||||
pCom = FindCommand(pSics,argv[6]);
|
||||
pCom = FindCommand(pSics,argv[7]);
|
||||
if(pCom)
|
||||
{
|
||||
pDum = (pDummy)pCom->pData;
|
||||
@ -313,13 +327,14 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
|
||||
}
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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
|
||||
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
|
||||
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.
|
||||
---------------------------------------------------------------------------*/
|
||||
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.
|
||||
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
|
||||
*/
|
||||
ClearScanVar(self->pScanner);
|
||||
AddScanVar(self->pScanner, pServ->pSics,pCon,scanVar,
|
||||
AddScanVar(self->pScanner, pServ->pSics,pCon,self->pCOmega,
|
||||
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
|
||||
|
1
mesure.h
1
mesure.h
@ -17,6 +17,7 @@
|
||||
/*--------------------- live & death --------------------------------------*/
|
||||
pMesure CreateMesure(pHKL pCryst, pScanData pScanner,
|
||||
pMotor pOmega, char *pom,
|
||||
pMotor p2Theta, char *p2t,
|
||||
char *pFileRoot,pDataNumber pDanu);
|
||||
void DeleteMesure(void *pData);
|
||||
|
||||
|
1
mesure.w
1
mesure.w
@ -25,6 +25,7 @@ The interface to this object consists of these functions:
|
||||
/*--------------------- live & death --------------------------------------*/
|
||||
pMesure CreateMesure(pHKL pCryst, pScanData pScanner,
|
||||
pMotor pOmega, char *pom,
|
||||
pMotor p2Theta, char *p2t,
|
||||
char *pFileRoot,pDataNumber pDanu);
|
||||
void DeleteMesure(void *pData);
|
||||
|
||||
|
2
motor.c
2
motor.c
@ -732,7 +732,7 @@ extern void KillPiPiezo(void *pData);
|
||||
iRet = MotorCheckBoundary(self,fNew,&fHard,pBueffel,511);
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,pBueffel,eStatus);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
SCSetInterrupt(pCon,eAbortOperation);
|
||||
return 0;
|
||||
}
|
||||
|
73
nxxml.h
Normal file
73
nxxml.h
Normal 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
|
@ -329,19 +329,23 @@ static int calculateAndDrive(ptasMot self, SConnection *pCon){
|
||||
switch(status){
|
||||
case ENERGYTOBIG:
|
||||
SCWrite(pCon,"ERROR: desired energy to big",eError);
|
||||
self->math->mustDrive = 0;
|
||||
return HWFault;
|
||||
break;
|
||||
|
||||
case UBNOMEMORY:
|
||||
SCWrite(pCon,"ERROR: out of memory calculating angles",eError);
|
||||
self->math->mustDrive = 0;
|
||||
return HWFault;
|
||||
break;
|
||||
case BADRMATRIX:
|
||||
SCWrite(pCon,"ERROR: bad crystallographic parameters or bad UB",eError);
|
||||
self->math->mustDrive = 0;
|
||||
return HWFault;
|
||||
break;
|
||||
case TRIANGLENOTCLOSED:
|
||||
SCWrite(pCon,"ERROR: cannot close scattering triangle",eError);
|
||||
self->math->mustDrive = 0;
|
||||
return HWFault;
|
||||
break;
|
||||
default:
|
||||
|
33
tasub.c
33
tasub.c
@ -490,7 +490,7 @@ static void listReflections(ptasUB self, SConnection *pCon){
|
||||
|
||||
Tcl_DStringInit(&list);
|
||||
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);
|
||||
status = LLDnodePtr2First(self->reflectionList);
|
||||
while(status == 1){
|
||||
@ -498,7 +498,7 @@ static void listReflections(ptasUB self, SConnection *pCon){
|
||||
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",
|
||||
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);
|
||||
status = LLDnodePtr2Next(self->reflectionList);
|
||||
}
|
||||
@ -510,6 +510,8 @@ static void listReflections(ptasUB self, SConnection *pCon){
|
||||
Tcl_DStringFree(&list);
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
/*-------------------------------------------------------------------*/
|
||||
static int addReflection(ptasUB self, SicsInterp *pSics,
|
||||
SConnection *pCon,
|
||||
int argc, char *argv[]){
|
||||
@ -597,18 +599,22 @@ static int addReflection(ptasUB self, SicsInterp *pSics,
|
||||
if(status != 1){
|
||||
return status;
|
||||
}
|
||||
r.qe.ki = maCalcK(self->machine.monochromator,angles.monochromator_two_theta);
|
||||
r.qe.kf = maCalcK(self->machine.analyzer,angles.analyzer_two_theta);
|
||||
r.qe.ki = maCalcK(self->machine.monochromator,r.angles.monochromator_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);
|
||||
Tcl_DStringInit(&list);
|
||||
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);
|
||||
snprintf(pBueffel,255,
|
||||
" %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.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);
|
||||
SCWrite(pCon,Tcl_DStringValue(&list),eValue);
|
||||
Tcl_DStringFree(&list);
|
||||
@ -669,12 +675,13 @@ static void printReflectionDiagnostik(ptasUB self, SConnection *pCon,
|
||||
|
||||
Tcl_DStringInit(&list);
|
||||
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);
|
||||
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.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);
|
||||
qe.ki = r.qe.ki;
|
||||
qe.kf = r.qe.kf;
|
||||
@ -683,10 +690,10 @@ static void printReflectionDiagnostik(ptasUB self, SConnection *pCon,
|
||||
qe.ql = r.qe.ql;
|
||||
calcAllTasAngles(&self->machine,qe,&angles);
|
||||
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,
|
||||
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);
|
||||
angles.a3 = r.angles.a3;
|
||||
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;
|
||||
calcTasQEPosition(&self->machine,angles,&qe);
|
||||
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,
|
||||
angles.sgu, angles.sgl, qe.ki, qe.kf);
|
||||
angles.sgu, angles.sgl, KtoEnergy(qe.ki), KtoEnergy(qe.kf));
|
||||
Tcl_DStringAppend(&list,line,-1);
|
||||
SCWrite(pCon,Tcl_DStringValue(&list),eWarning);
|
||||
Tcl_DStringFree(&list);
|
||||
|
11
tasublib.c
11
tasublib.c
@ -260,7 +260,9 @@ static MATRIX buildTVMatrix(MATRIX U1V, MATRIX U2V){
|
||||
MATRIX T, T3V;
|
||||
int i;
|
||||
|
||||
normalizeVector(U2V);
|
||||
T3V = vectorCrossProduct(U1V,U2V);
|
||||
normalizeVector(T3V);
|
||||
if(T3V == NULL){
|
||||
return NULL;
|
||||
}
|
||||
@ -340,12 +342,17 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe,
|
||||
}
|
||||
om = Acosd(R[0][0]/sq);
|
||||
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]);
|
||||
if(ABS(sq) < .00001){
|
||||
return BADRMATRIX;
|
||||
}
|
||||
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);
|
||||
if(QC == NULL){
|
||||
@ -355,7 +362,7 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe,
|
||||
q = 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));
|
||||
if(cos2t > 1.){
|
||||
if(ABS(cos2t) > 1.){
|
||||
return TRIANGLENOTCLOSED;
|
||||
}
|
||||
angles->sample_two_theta = ss*Acosd(cos2t);
|
||||
|
Reference in New Issue
Block a user