- 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 <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);
|
||||||
|
@ -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;
|
||||||
|
49
mesure.c
49
mesure.c
@ -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
|
||||||
|
1
mesure.h
1
mesure.h
@ -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);
|
||||||
|
|
||||||
|
1
mesure.w
1
mesure.w
@ -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);
|
||||||
|
|
||||||
|
2
motor.c
2
motor.c
@ -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
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){
|
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
33
tasub.c
@ -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);
|
||||||
|
11
tasublib.c
11
tasublib.c
@ -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);
|
||||||
|
Reference in New Issue
Block a user