- Added a local maximum search for 2D detectors in support of peak
search for TRICS
This commit is contained in:
2
Makefile
2
Makefile
@ -48,7 +48,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
|||||||
circular.o el755driv.o maximize.o sicscron.o tecsdriv.o sanscook.o \
|
circular.o el755driv.o maximize.o sicscron.o tecsdriv.o sanscook.o \
|
||||||
tasinit.o tasutil.o t_rlp.o t_conv.o d_sign.o d_mod.o \
|
tasinit.o tasutil.o t_rlp.o t_conv.o d_sign.o d_mod.o \
|
||||||
tasdrive.o tasscan.o synchronize.o definealias.o swmotor.o t_update.o \
|
tasdrive.o tasscan.o synchronize.o definealias.o swmotor.o t_update.o \
|
||||||
hmcontrol.o userscan.o slsmagnet.o rs232controller.o
|
hmcontrol.o userscan.o slsmagnet.o rs232controller.o lomax.o
|
||||||
|
|
||||||
MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
|
MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
|
||||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||||
|
2
danu.dat
2
danu.dat
@ -1,3 +1,3 @@
|
|||||||
103
|
123
|
||||||
NEVER, EVER modify or delete this file
|
NEVER, EVER modify or delete this file
|
||||||
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
476
lomax.c
Normal file
476
lomax.c
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
L o c a l M a x i m u m
|
||||||
|
|
||||||
|
This is a module for searching a local maximum in a 2D histogram as
|
||||||
|
collected at TRICS.
|
||||||
|
|
||||||
|
copyright: see copyright.h
|
||||||
|
|
||||||
|
Mark Koennecke, November 2001
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <tcl.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "fortify.h"
|
||||||
|
#include "sics.h"
|
||||||
|
#include "lomax.h"
|
||||||
|
#include "lomax.i"
|
||||||
|
#include "HistMem.h"
|
||||||
|
|
||||||
|
#define WINDOW 0
|
||||||
|
#define THRESHOLD 1
|
||||||
|
#define STEEPNESS 2
|
||||||
|
#define COGWINDOW 3
|
||||||
|
#define COGCONTOUR 4
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
static int testBoundaries(int xsize, int ysize, int window,
|
||||||
|
int i, int j)
|
||||||
|
{
|
||||||
|
int half;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if the window touches the data boundary the result is probably not
|
||||||
|
very useful. Discarding these cases early on also protects us
|
||||||
|
against data array overrun problems.
|
||||||
|
*/
|
||||||
|
|
||||||
|
half = window/2;
|
||||||
|
|
||||||
|
if( i - half < 0 || i + half > xsize)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( j - half < 0 || j + half > ysize)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
static int testSteepness(int *iData, int xsize, int ysize,
|
||||||
|
int i, int j, int window, int steepness)
|
||||||
|
{
|
||||||
|
int testValue, x, y, half;
|
||||||
|
int *iPtr;
|
||||||
|
|
||||||
|
|
||||||
|
testValue = iData[j * xsize + i] - steepness;
|
||||||
|
half = window/2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
test upper row
|
||||||
|
*/
|
||||||
|
iPtr = iData + (j - half) * xsize + i - half;
|
||||||
|
for(x = 0; x < window; x++)
|
||||||
|
{
|
||||||
|
if(iPtr[x] > testValue)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
test lower row
|
||||||
|
*/
|
||||||
|
iPtr = iData + (j + half) * xsize + i - half;
|
||||||
|
for(x = 0; x < window; x++)
|
||||||
|
{
|
||||||
|
if(iPtr[x] > testValue)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
test columns
|
||||||
|
*/
|
||||||
|
for(y = j - half; y < j + half; y++)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
left
|
||||||
|
*/
|
||||||
|
if(iData[y*xsize + i - half] > testValue)
|
||||||
|
return 0;
|
||||||
|
/*
|
||||||
|
right
|
||||||
|
*/
|
||||||
|
if(iData[y*xsize + i + half] > testValue)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
static int testMaximum(int *iData, int xsize, int ysize,
|
||||||
|
int i, int j, int window)
|
||||||
|
{
|
||||||
|
int testValue, x, y, half;
|
||||||
|
int *iPtr;
|
||||||
|
|
||||||
|
testValue = iData[j * xsize + i];
|
||||||
|
half = window/2;
|
||||||
|
|
||||||
|
for(y = j - half; y < j + half; y++)
|
||||||
|
{
|
||||||
|
iPtr = iData + y * xsize + i - half;
|
||||||
|
for(x = 0; x < window; x++)
|
||||||
|
{
|
||||||
|
if(iPtr[x] > testValue)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
int testLocalMaximum(int *iData, int xsize, int ysize,
|
||||||
|
int i, int j,
|
||||||
|
int window, int steepness, int threshold,
|
||||||
|
int *intensity)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!testBoundaries(xsize,ysize,window,i,j))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
if(!testMaximum(iData,xsize,ysize,i,j,window))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(iData[j * xsize + i] < threshold)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!testSteepness(iData,xsize,ysize,i,j,window, steepness))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*intensity = iData[j * xsize + i];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
int calculateCOG(int *iData, int xsize, int ysize,
|
||||||
|
int *i, int *j, int *intensity,
|
||||||
|
int cogWindow,
|
||||||
|
float contour)
|
||||||
|
{
|
||||||
|
int x, xLow, xMax, y, yLow, yMax;
|
||||||
|
int threshold;
|
||||||
|
float cogTotal, cogX, cogY;
|
||||||
|
int *iPtr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
preparations
|
||||||
|
*/
|
||||||
|
xLow = *i - cogWindow/2;
|
||||||
|
if(xLow < 0)
|
||||||
|
xLow = 0;
|
||||||
|
xMax = *i + cogWindow/2;
|
||||||
|
if(xLow >= xsize)
|
||||||
|
xMax = xsize-1;
|
||||||
|
|
||||||
|
yLow = *j - cogWindow/2;
|
||||||
|
if(yLow < 0)
|
||||||
|
yLow = 0;
|
||||||
|
yMax = *j + cogWindow/2;
|
||||||
|
if(yLow >= ysize)
|
||||||
|
yMax = ysize-1;
|
||||||
|
|
||||||
|
threshold = (int)(float)iData[*j * xsize + *i] * contour;
|
||||||
|
|
||||||
|
/*
|
||||||
|
build the sums
|
||||||
|
*/
|
||||||
|
cogTotal = cogY = cogX = .0;
|
||||||
|
for(y = yLow; y < yMax; y++)
|
||||||
|
{
|
||||||
|
iPtr = iData + y *xsize;
|
||||||
|
for(x = xLow; x < xMax; x++)
|
||||||
|
{
|
||||||
|
if(iPtr[x] > threshold)
|
||||||
|
{
|
||||||
|
cogTotal += iPtr[x];
|
||||||
|
cogY += y * iPtr[x];
|
||||||
|
cogX += x * iPtr[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(cogTotal < .0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*i = (int)nintf(cogX/cogTotal);
|
||||||
|
*j = (int)nintf(cogY/cogTotal);
|
||||||
|
*intensity = (int)cogTotal;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
static int checkHM(pHistMem *pHM, SicsInterp *pSics, SConnection *pCon,
|
||||||
|
char *name, int *iDim)
|
||||||
|
{
|
||||||
|
CommandList *pCom = NULL;
|
||||||
|
char pBueffel[256];
|
||||||
|
int nDim;
|
||||||
|
|
||||||
|
pCom = FindCommand(pSics, name);
|
||||||
|
if(!pCom)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: histogram memory %s not found", name);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!pCom->pData)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: histogram memory %s not found", name);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*pHM = (pHistMem)pCom->pData;
|
||||||
|
if(!iHasType(*pHM, "HistMem"))
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: %s is no histogram memory!", name);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
we now know that we have a histogram memory, now check Sizes
|
||||||
|
*/
|
||||||
|
GetHistDim(*pHM,iDim,&nDim);
|
||||||
|
if(nDim < 2)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: %s is not 2 dimensional!", name);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
int LoMaxAction(SConnection *pCon, SicsInterp *pSics,
|
||||||
|
void *pData, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pLoMax self = NULL;
|
||||||
|
char pBueffel[256], pNum[20];
|
||||||
|
int iRet, i, j, intensity;
|
||||||
|
int iDim[10], nDim;
|
||||||
|
pHistMem pHM = NULL;
|
||||||
|
CommandList *pCom = NULL;
|
||||||
|
Tcl_DString result;
|
||||||
|
int window;
|
||||||
|
int *iData;
|
||||||
|
double dVal;
|
||||||
|
ObPar *ob = NULL;
|
||||||
|
|
||||||
|
self = (pLoMax)pData;
|
||||||
|
assert(pCon);
|
||||||
|
assert(pSics);
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
/*
|
||||||
|
we need arguments
|
||||||
|
*/
|
||||||
|
if(argc < 2)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: insufficient number of arguments to %s",
|
||||||
|
argv[0]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
interpret arguments
|
||||||
|
*/
|
||||||
|
strtolower(argv[1]);
|
||||||
|
if(strcmp(argv[1],"search") == 0)
|
||||||
|
{
|
||||||
|
if(argc < 3)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: insufficient number of arguments to %s.search",
|
||||||
|
argv[0]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!checkHM(&pHM, pSics,pCon, argv[2],iDim))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Tcl_DStringInit(&result);
|
||||||
|
Tcl_DStringStartSublist(&result);
|
||||||
|
iData = GetHistogramPointer(pHM,pCon);
|
||||||
|
window = (int)ObVal(self->pParam,WINDOW);
|
||||||
|
for(i = 0 + window/2; i < iDim[0] - window/2; i++)
|
||||||
|
{
|
||||||
|
for(j = 0 + window/2; j < iDim[1] - window/2; j++)
|
||||||
|
{
|
||||||
|
if(testLocalMaximum(iData,iDim[0], iDim[1],
|
||||||
|
i,j,
|
||||||
|
(int)ObVal(self->pParam,WINDOW),
|
||||||
|
(int)ObVal(self->pParam,STEEPNESS),
|
||||||
|
(int)ObVal(self->pParam,THRESHOLD),
|
||||||
|
&intensity))
|
||||||
|
{
|
||||||
|
Tcl_DStringStartSublist(&result);
|
||||||
|
sprintf(pNum,"%d", i);
|
||||||
|
Tcl_DStringAppendElement(&result,pNum);
|
||||||
|
sprintf(pNum,"%d", j);
|
||||||
|
Tcl_DStringAppendElement(&result,pNum);
|
||||||
|
sprintf(pNum,"%d", intensity);
|
||||||
|
Tcl_DStringAppendElement(&result,pNum);
|
||||||
|
Tcl_DStringEndSublist(&result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tcl_DStringEndSublist(&result);
|
||||||
|
SCWrite(pCon,Tcl_DStringValue(&result),eValue);
|
||||||
|
Tcl_DStringFree(&result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1],"cog") == 0) /* COG calculation */
|
||||||
|
{
|
||||||
|
if(argc < 5)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: insufficient number of arguments to %s.cog",
|
||||||
|
argv[0]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!checkHM(&pHM, pSics,pCon, argv[2],iDim))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(Tcl_GetInt(pSics->pTcl,argv[3],&i)!= TCL_OK)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[2]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(Tcl_GetInt(pSics->pTcl,argv[4],&j)!= TCL_OK)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[2]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Tcl_DStringInit(&result);
|
||||||
|
Tcl_DStringStartSublist(&result);
|
||||||
|
iData = GetHistogramPointer(pHM,pCon);
|
||||||
|
window = (int)ObVal(self->pParam,COGWINDOW);
|
||||||
|
iRet = calculateCOG(iData,iDim[0], iDim[1], &i, &j, &intensity,
|
||||||
|
window, ObVal(self->pParam,COGCONTOUR));
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: no intensity in data",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sprintf(pNum,"%d", i);
|
||||||
|
Tcl_DStringAppendElement(&result,pNum);
|
||||||
|
sprintf(pNum,"%d", j);
|
||||||
|
Tcl_DStringAppendElement(&result,pNum);
|
||||||
|
sprintf(pNum,"%d", intensity);
|
||||||
|
Tcl_DStringAppendElement(&result,pNum);
|
||||||
|
Tcl_DStringEndSublist(&result);
|
||||||
|
SCWrite(pCon,Tcl_DStringValue(&result),eValue);
|
||||||
|
Tcl_DStringFree(&result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* we are handling one of the parameter commands
|
||||||
|
*/
|
||||||
|
if(argc > 2) /* set case */
|
||||||
|
{
|
||||||
|
if(Tcl_GetDouble(pSics->pTcl,argv[2],&dVal) != TCL_OK)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[2]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ObParSet(self->pParam,argv[0],argv[1],(float)dVal,pCon);
|
||||||
|
}
|
||||||
|
else /* read case */
|
||||||
|
{
|
||||||
|
ob = ObParFind(self->pParam,argv[1]);
|
||||||
|
if(!ob)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: parameter %s not found or wrong command",
|
||||||
|
argv[1]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sprintf(pBueffel,"%s.%s = %f",argv[0],argv[1],ob->fVal);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
not reached
|
||||||
|
*/
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
static void KillLoMax(void *pData)
|
||||||
|
{
|
||||||
|
pLoMax self = (pLoMax)pData;
|
||||||
|
if(!self)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(self->pDes)
|
||||||
|
DeleteDescriptor(self->pDes);
|
||||||
|
if(self->pParam)
|
||||||
|
ObParDelete(self->pParam);
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
int LoMaxFactory(SConnection *pCon, SicsInterp *pSics,
|
||||||
|
void *pData, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pLoMax pNew = NULL;
|
||||||
|
|
||||||
|
if(argc < 2)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: Insufficient number of arguments to LoMaxfactory",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNew = (pLoMax)malloc(sizeof(LoMax));
|
||||||
|
if(!pNew)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: out of memory creating local maximum searcher",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(pNew,0,sizeof(LoMax));
|
||||||
|
|
||||||
|
/*
|
||||||
|
create Descriptor
|
||||||
|
*/
|
||||||
|
pNew->pDes = CreateDescriptor("Local Maximum Detector");
|
||||||
|
if(!pNew->pDes)
|
||||||
|
{
|
||||||
|
KillLoMax(pNew);
|
||||||
|
SCWrite(pCon,"ERROR: out of memory creating local maximum searcher",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
create and install parameters
|
||||||
|
*/
|
||||||
|
pNew->pParam = ObParCreate(5);
|
||||||
|
if(!pNew->pParam)
|
||||||
|
{
|
||||||
|
KillLoMax(pNew);
|
||||||
|
SCWrite(pCon,"ERROR: out of memory creating local maximum searcher",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ObParInit(pNew->pParam,WINDOW,"window",10,usUser);
|
||||||
|
ObParInit(pNew->pParam,THRESHOLD,"threshold",30,usUser);
|
||||||
|
ObParInit(pNew->pParam,STEEPNESS,"steepness",5,usUser);
|
||||||
|
ObParInit(pNew->pParam,COGWINDOW,"cogwindow",50,usUser);
|
||||||
|
ObParInit(pNew->pParam,COGCONTOUR,"cogcontour",.2,usUser);
|
||||||
|
|
||||||
|
return AddCommand(pSics,
|
||||||
|
argv[1],
|
||||||
|
LoMaxAction,
|
||||||
|
KillLoMax,
|
||||||
|
pNew);
|
||||||
|
}
|
||||||
|
|
37
lomax.h
Normal file
37
lomax.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
L o c a l M a x i m u m
|
||||||
|
|
||||||
|
This is a module for searching a local maximum in a 2D histogram as
|
||||||
|
collected at TRICS.
|
||||||
|
|
||||||
|
copyright: see copyright.h
|
||||||
|
|
||||||
|
Mark Koennecke, November 2001
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#ifndef LOCALMAXIMUM
|
||||||
|
#define LOCALMAXIMUM
|
||||||
|
#include "obpar.h"
|
||||||
|
|
||||||
|
typedef struct __LOMAX *pLoMax;
|
||||||
|
|
||||||
|
|
||||||
|
int LoMaxAction(SConnection *pCon, SicsInterp *pSics,
|
||||||
|
void *pData, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int LoMaxFactory(SConnection *pCon, SicsInterp *pSics,
|
||||||
|
void *pData, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int testLocalMaximum(int *iData, int xsize, int ysize,
|
||||||
|
int i, int j,
|
||||||
|
int window, int threshold, int steepness,
|
||||||
|
int *intensity);
|
||||||
|
int calculateCOG(int *iData, int xsize, int ysize,
|
||||||
|
int *i, int *j, int *intensity,
|
||||||
|
int cogWindow,
|
||||||
|
float contour);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
19
lomax.i
Normal file
19
lomax.i
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
L o c a l M a x i m u m
|
||||||
|
|
||||||
|
This is a module for searching a local maximum in a 2D histogram as
|
||||||
|
collected at TRICS. These are internal definitions only and are
|
||||||
|
supposed to be included only into lomax.c
|
||||||
|
|
||||||
|
copyright: see copyright.h
|
||||||
|
|
||||||
|
Mark Koennecke, November 2001
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
typedef struct __LOMAX {
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
ObPar *pParam;
|
||||||
|
}LoMax;
|
||||||
|
|
||||||
|
|
104
lomax.w
Normal file
104
lomax.w
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
\subsection{Local Maximum Search}
|
||||||
|
This module implements searching for local maxima in a 2D histogram of
|
||||||
|
data. It is mainly intended for use at TRICS where initially
|
||||||
|
reflections need to be searched for the determination of a UB
|
||||||
|
matrix. The local maximum algorithm is a little more sophisticated
|
||||||
|
then commonly used in that the window of the search is user definable,
|
||||||
|
and a valid maximum has to have a certain steepness against the
|
||||||
|
bordering points in order to be valid. Another validity test is a
|
||||||
|
threshold which must be reached. All these enhancements should reduce
|
||||||
|
the number of false maxima which may turn up as the result of horrible
|
||||||
|
measurement statistics.
|
||||||
|
|
||||||
|
The position and intensity of a local maximum found can be refined further
|
||||||
|
with a center of gravity calculation within a given window including all
|
||||||
|
data points above a certain threshold expressed as a fraction of the local
|
||||||
|
maximums intensity.
|
||||||
|
|
||||||
|
Again this module has a little data structure:
|
||||||
|
|
||||||
|
@d lomaxdata @{
|
||||||
|
typedef struct __LOMAX {
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
ObPar *pParam;
|
||||||
|
}LoMax;
|
||||||
|
@}
|
||||||
|
The fields are:
|
||||||
|
\begin{description}
|
||||||
|
\item[pDes] The standard object descriptor.
|
||||||
|
\item[pParam] The parameters of this object.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
The exported interface is simple: just the necessary functions for
|
||||||
|
representing the object in the interpreter and a function which allows
|
||||||
|
to use the local maxima search from another module. If the latter is
|
||||||
|
ever needed.
|
||||||
|
|
||||||
|
@d lomaxint @{
|
||||||
|
int LoMaxAction(SConnection *pCon, SicsInterp *pSics,
|
||||||
|
void *pData, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int LoMaxFactory(SConnection *pCon, SicsInterp *pSics,
|
||||||
|
void *pData, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int testLocalMaximum(int *iData, int xsize, int ysize,
|
||||||
|
int i, int j,
|
||||||
|
int window, int threshold, int steepness,
|
||||||
|
int *intensity);
|
||||||
|
int calculateCOG(int *iData, int xsize, int ysize,
|
||||||
|
int *i, int *j, int *intensity,
|
||||||
|
int cogWindow,
|
||||||
|
float contour);
|
||||||
|
|
||||||
|
@}
|
||||||
|
|
||||||
|
testLocalMaxima checks if point i, j is a valid local maximum. It
|
||||||
|
returns true (1) if this is the case, or false (0) if this is not the
|
||||||
|
case. The window parameter describes how much points shall be searched
|
||||||
|
in each direction.
|
||||||
|
|
||||||
|
calculateCOG calculates the center of gravity for point i, j,. Points within a
|
||||||
|
sqaure window of size cogWindow are considered. Only points whose
|
||||||
|
intensity obeys I \gt I(i,j)*countour are used for the COG
|
||||||
|
calculation. The position of the maximum (i,j) and its intensity are
|
||||||
|
updated by calculateCOG.
|
||||||
|
|
||||||
|
|
||||||
|
@o lomax.h @{
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
L o c a l M a x i m u m
|
||||||
|
|
||||||
|
This is a module for searching a local maximum in a 2D histogram as
|
||||||
|
collected at TRICS.
|
||||||
|
|
||||||
|
copyright: see copyright.h
|
||||||
|
|
||||||
|
Mark Koennecke, November 2001
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#ifndef LOCALMAXIMUM
|
||||||
|
#define LOCALMAXIMUM
|
||||||
|
#include "obpar.h"
|
||||||
|
|
||||||
|
typedef struct __LOMAX *pLoMax;
|
||||||
|
|
||||||
|
@<lomaxint@>
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@}
|
||||||
|
|
||||||
|
@o lomax.i @{
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
L o c a l M a x i m u m
|
||||||
|
|
||||||
|
This is a module for searching a local maximum in a 2D histogram as
|
||||||
|
collected at TRICS. These are internal definitions only and are
|
||||||
|
supposed to be included only into lomax.c
|
||||||
|
|
||||||
|
copyright: see copyright.h
|
||||||
|
|
||||||
|
Mark Koennecke, November 2001
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
@<lomaxdata@>
|
||||||
|
|
||||||
|
@}
|
@ -395,8 +395,8 @@ name of hkl object holding crystallographic information
|
|||||||
NXputdata(hfil,lData);
|
NXputdata(hfil,lData);
|
||||||
NXsetdimname(hfil,0,"frame_x");
|
NXsetdimname(hfil,0,"frame_x");
|
||||||
NXsetdimname(hfil,1,"frame_y");
|
NXsetdimname(hfil,1,"frame_y");
|
||||||
*/
|
|
||||||
NXclosedata(hfil);
|
NXclosedata(hfil);
|
||||||
|
*/
|
||||||
|
|
||||||
fVal = fTTheta + self->hm1off;
|
fVal = fTTheta + self->hm1off;
|
||||||
NXDputalias(hfil,self->pDict,"frame2theta",&fVal);
|
NXDputalias(hfil,self->pDict,"frame2theta",&fVal);
|
||||||
@ -424,8 +424,8 @@ name of hkl object holding crystallographic information
|
|||||||
NXputdata(hfil,lData);
|
NXputdata(hfil,lData);
|
||||||
NXsetdimname(hfil,0,"frame_x");
|
NXsetdimname(hfil,0,"frame_x");
|
||||||
NXsetdimname(hfil,1,"frame_y");
|
NXsetdimname(hfil,1,"frame_y");
|
||||||
*/
|
|
||||||
NXclosedata(hfil);
|
NXclosedata(hfil);
|
||||||
|
*/
|
||||||
|
|
||||||
fVal = fTTheta + self->hm2Off;
|
fVal = fTTheta + self->hm2Off;
|
||||||
NXDputalias(hfil,self->pDict,"frame2theta",&fVal);
|
NXDputalias(hfil,self->pDict,"frame2theta",&fVal);
|
||||||
@ -454,9 +454,9 @@ name of hkl object holding crystallographic information
|
|||||||
NXputdata(hfil,lData);
|
NXputdata(hfil,lData);
|
||||||
NXsetdimname(hfil,0,"frame_x");
|
NXsetdimname(hfil,0,"frame_x");
|
||||||
NXsetdimname(hfil,1,"frame_y");
|
NXsetdimname(hfil,1,"frame_y");
|
||||||
|
NXclosedata(hfil);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NXclosedata(hfil);
|
|
||||||
|
|
||||||
fVal = fTTheta + self->hm3Off;
|
fVal = fTTheta + self->hm3Off;
|
||||||
NXDputalias(hfil,self->pDict,"frame2theta",&fVal);
|
NXDputalias(hfil,self->pDict,"frame2theta",&fVal);
|
||||||
|
3
ofac.c
3
ofac.c
@ -105,6 +105,7 @@
|
|||||||
#include "swmotor.h"
|
#include "swmotor.h"
|
||||||
#include "hmcontrol.h"
|
#include "hmcontrol.h"
|
||||||
#include "rs232controller.h"
|
#include "rs232controller.h"
|
||||||
|
#include "lomax.h"
|
||||||
/*----------------------- Server options creation -------------------------*/
|
/*----------------------- Server options creation -------------------------*/
|
||||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -285,6 +286,7 @@
|
|||||||
AddCommand(pInter,"MakeSWMotor",MakeSWMotor,NULL,NULL);
|
AddCommand(pInter,"MakeSWMotor",MakeSWMotor,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeHMControl",MakeHMControl,NULL,NULL);
|
AddCommand(pInter,"MakeHMControl",MakeHMControl,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeRS232Controller",RS232Factory,NULL,NULL);
|
AddCommand(pInter,"MakeRS232Controller",RS232Factory,NULL,NULL);
|
||||||
|
AddCommand(pInter,"MakeMaxDetector",LoMaxFactory,NULL,NULL);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void KillIniCommands(SicsInterp *pSics)
|
static void KillIniCommands(SicsInterp *pSics)
|
||||||
@ -342,6 +344,7 @@
|
|||||||
RemoveCommand(pSics,"MakeSWMotor");
|
RemoveCommand(pSics,"MakeSWMotor");
|
||||||
RemoveCommand(pSics,"MakeHMControl");
|
RemoveCommand(pSics,"MakeHMControl");
|
||||||
RemoveCommand(pSics,"MakeRS232Controller");
|
RemoveCommand(pSics,"MakeRS232Controller");
|
||||||
|
RemoveCommand(pSics,"MakeMaxDetector");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
208
peaksearch.tcl
Normal file
208
peaksearch.tcl
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# peaksearch a peak search utility for TRICS using the PSD detectors.
|
||||||
|
#
|
||||||
|
# Mark Koennecke, November 2001
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
proc initPeakSearch {} {
|
||||||
|
VarMake ps.phiStart Float User
|
||||||
|
ps.phiStart 0
|
||||||
|
VarMake ps.phiEnd Float User
|
||||||
|
ps.phiEnd 180
|
||||||
|
VarMake ps.phiStep Float User
|
||||||
|
ps.phiStep 3.
|
||||||
|
|
||||||
|
VarMake ps.chiStart Float User
|
||||||
|
ps.chiStart 0
|
||||||
|
VarMake ps.chiEnd Float User
|
||||||
|
ps.chiEnd 180
|
||||||
|
VarMake ps.chiStep Float User
|
||||||
|
ps.chiStep 12.
|
||||||
|
|
||||||
|
VarMake ps.omStart Float User
|
||||||
|
ps.omStart 0
|
||||||
|
VarMake ps.omEnd Float User
|
||||||
|
ps.omEnd 30
|
||||||
|
VarMake ps.omStep Float User
|
||||||
|
ps.omStep 3.
|
||||||
|
|
||||||
|
VarMake ps.sttStart Float User
|
||||||
|
ps.sttStart 5
|
||||||
|
VarMake ps.sttEnd Float User
|
||||||
|
ps.sttEnd 70
|
||||||
|
VarMake ps.sttStep Float User
|
||||||
|
ps.sttStep 3.
|
||||||
|
|
||||||
|
VarMake ps.threshold Int User
|
||||||
|
ps.threshold 30
|
||||||
|
VarMake ps.steepness Int User
|
||||||
|
ps.steepness 3
|
||||||
|
VarMake ps.window Int User
|
||||||
|
ps.window 7
|
||||||
|
VarMake ps.cogwindow Int User
|
||||||
|
ps.cogwindow 60
|
||||||
|
VarMake ps.cogcontour Float User
|
||||||
|
ps.cogcontour .2
|
||||||
|
|
||||||
|
VarMake ps.countmode Text User
|
||||||
|
ps.countmode monitor
|
||||||
|
|
||||||
|
VarMake ps.preset Float User
|
||||||
|
ps.preset 1000
|
||||||
|
|
||||||
|
Publish ps.phirange User
|
||||||
|
Publish ps.chirange User
|
||||||
|
Publish ps.omrange User
|
||||||
|
Publish ps.sttrange User
|
||||||
|
Publish ps.countpar User
|
||||||
|
Publish ps.maxpar User
|
||||||
|
#------- these are for debugging only!
|
||||||
|
Publish checkomega User
|
||||||
|
Publish optimizepeak User
|
||||||
|
}
|
||||||
|
#--------------------------------------------------------------------------
|
||||||
|
proc ps.phirange args {
|
||||||
|
if { [llength $args] >= 3 } {
|
||||||
|
ps.phiStart [lindex $args 0]
|
||||||
|
ps.phiEnd [lindex $args 1]
|
||||||
|
ps.phiStep [lindex $args 2]
|
||||||
|
}
|
||||||
|
clientput "Peak Search Phi Range:"
|
||||||
|
return [format " Start = %6.2f, End = %6.2f, Step = %6.2f" \
|
||||||
|
[SplitReply [ps.phiStart]] [SplitReply [ps.phiEnd]] \
|
||||||
|
[SplitReply [ps.phiStep]]]
|
||||||
|
}
|
||||||
|
#--------------------------------------------------------------------------
|
||||||
|
proc ps.chirange args {
|
||||||
|
if { [llength $args] >= 3 } {
|
||||||
|
ps.chiStart [lindex $args 0]
|
||||||
|
ps.chiEnd [lindex $args 1]
|
||||||
|
ps.chiStep [lindex $args 2]
|
||||||
|
}
|
||||||
|
clientput "Peak Search Chi Range:"
|
||||||
|
return [format " Start = %6.2f, End = %6.2f, Step = %6.2f" \
|
||||||
|
[SplitReply [ps.chiStart]] [SplitReply [ps.chiEnd]] \
|
||||||
|
[SplitReply [ps.chiStep]]]
|
||||||
|
}
|
||||||
|
#--------------------------------------------------------------------------
|
||||||
|
proc ps.omrange args {
|
||||||
|
if { [llength $args] >= 3 } {
|
||||||
|
ps.omStart [lindex $args 0]
|
||||||
|
ps.omEnd [lindex $args 1]
|
||||||
|
ps.omStep [lindex $args 2]
|
||||||
|
}
|
||||||
|
clientput "Peak Search Omega Range:"
|
||||||
|
return [format " Start = %6.2f, End = %6.2f, Step = %6.2f" \
|
||||||
|
[SplitReply [ps.omStart]] [SplitReply [ps.omEnd]] \
|
||||||
|
[SplitReply [ps.omStep]]]
|
||||||
|
}
|
||||||
|
#--------------------------------------------------------------------------
|
||||||
|
proc ps.sttrange args {
|
||||||
|
if { [llength $args] >= 3 } {
|
||||||
|
ps.sttStart [lindex $args 0]
|
||||||
|
ps.sttEnd [lindex $args 1]
|
||||||
|
ps.sttStep [lindex $args 2]
|
||||||
|
}
|
||||||
|
clientput "Peak Search Two Theta Range:"
|
||||||
|
return [format " Start = %6.2f, End = %6.2f, Step = %6.2f" \
|
||||||
|
[SplitReply [ps.sttStart]] [SplitReply [ps.sttEnd]] \
|
||||||
|
[SplitReply [ps.sttStep]]]
|
||||||
|
}
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
proc ps.countpar args {
|
||||||
|
if { [llength $args] >= 2 } {
|
||||||
|
if { [catch {counter setmode [lindex $args 0]} msg] != 0} {
|
||||||
|
error "ERROR: Invalid countmode specified"
|
||||||
|
}
|
||||||
|
ps.countmode [lindex $args 0]
|
||||||
|
ps.preset [lindex $args 1]
|
||||||
|
}
|
||||||
|
clientput "Peak Search Count Parameters:"
|
||||||
|
return [format " Mode = %s, Preset = %12.2f" \
|
||||||
|
[SplitReply [ps.countmode]] [SplitReply [ps.preset]]]
|
||||||
|
}
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
proc ps.maxpar args {
|
||||||
|
if { [llength $args] >= 5 } {
|
||||||
|
ps.window [lindex $args 0]
|
||||||
|
ps.threshold [lindex $args 1]
|
||||||
|
ps.steepness [lindex $args 2]
|
||||||
|
ps.cogwindow [lindex $args 3]
|
||||||
|
ps.cogcontour [lindex $args 4]
|
||||||
|
}
|
||||||
|
clientput "Peak Search Maximum Detection Parameters:"
|
||||||
|
set t1 [format " Window = %d, Threshold = %d, Steepness = %d" \
|
||||||
|
[SplitReply [ps.window]] [SplitReply [ps.threshold]] \
|
||||||
|
[SplitReply [ps.steepness] ]]
|
||||||
|
set t2 [format " COGWindow = %d, COGcontour = %f " \
|
||||||
|
[SplitReply [ps.cogwindow]] [SplitReply [ps.cogcontour]]]
|
||||||
|
return [format "%s\n%s" $t1 $t2]
|
||||||
|
}
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
proc checknewomega {omega maxIntensity} {
|
||||||
|
if {[catch {drive $omega} msg] != 0} {
|
||||||
|
error $msg
|
||||||
|
}
|
||||||
|
if {[catch {hmc start [SplitReply [ps.preset]] [SplitReply \
|
||||||
|
[ps.countmode]]} msg] != 0} {
|
||||||
|
error $msg
|
||||||
|
}
|
||||||
|
if {[catch {Success} msg] != 0} {
|
||||||
|
error $msg
|
||||||
|
}
|
||||||
|
if { [catch {lomax cog $hm $x $y} result] != 0} {
|
||||||
|
error "Failed to calculate COG"
|
||||||
|
}
|
||||||
|
if {[lindex $result 2] > $maxIntensity } {
|
||||||
|
return $result
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
proc optimizepeak {hm x y} {
|
||||||
|
if { [catch {lomax cog $hm $x $y} result] != 0} {
|
||||||
|
error "Failed to calculate COG"
|
||||||
|
}
|
||||||
|
set xMax [lindex $result 0]
|
||||||
|
set ymax [lindex $result 1]
|
||||||
|
set maxIntensity [lindex $result 2]
|
||||||
|
set maxOmega [SplitReply [om]]
|
||||||
|
set startOmega $maxOmega
|
||||||
|
#--------- move to positive omega until maximum found
|
||||||
|
while {1} {
|
||||||
|
set newOm [expr [SplitReply [om]] + [SplitReply [ps.omStep]]]
|
||||||
|
if {[catch {checknewomega $newOm $maxIntensity} result] != 0} {
|
||||||
|
error $result
|
||||||
|
}
|
||||||
|
if {$result != 0} {
|
||||||
|
set xMax [lindex $result 0]
|
||||||
|
set yMax [lindex $result 1]
|
||||||
|
set maxIntensity [lindex $result 2]
|
||||||
|
set maxOmega [SplitReply [om]]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#--------- if maxOmega is still startOmega then we were on the right
|
||||||
|
# side of the peak. In this case try to find the maximum in
|
||||||
|
# negative direction
|
||||||
|
if {$maxOmega == $startOmega} {
|
||||||
|
while {1} {
|
||||||
|
set newOm [expr [SplitReply [om]] - [SplitReply [ps.omStep]]]
|
||||||
|
if {[catch {checknewomega $newOm $maxIntensity} result] != 0} {
|
||||||
|
error $result
|
||||||
|
}
|
||||||
|
if {$result != 0} {
|
||||||
|
set xMax [lindex $result 0]
|
||||||
|
set yMax [lindex $result 1]
|
||||||
|
set maxIntensity [lindex $result 2]
|
||||||
|
set maxOmega [SplitReply [om]]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#----------- print the results we have found
|
||||||
|
}
|
||||||
|
|
@ -1,30 +1,47 @@
|
|||||||
a5l.length 80.000000
|
ps.preset 20.000000
|
||||||
flightpathlength 0.000000
|
ps.preset setAccess 2
|
||||||
flightpathlength setAccess 1
|
ps.countmode timer
|
||||||
flightpath 0.000000
|
ps.countmode setAccess 2
|
||||||
flightpath setAccess 1
|
ps.cogcontour 0.200000
|
||||||
delay 2500.000000
|
ps.cogcontour setAccess 2
|
||||||
delay setAccess 1
|
ps.cogwindow 60
|
||||||
hm CountMode timer
|
ps.cogwindow setAccess 2
|
||||||
hm preset 100.000000
|
ps.window 7
|
||||||
hm genbin 120.000000 35.000000 512
|
ps.window setAccess 2
|
||||||
hm init
|
ps.steepness 2
|
||||||
datafile focus-1001848.hdf
|
ps.steepness setAccess 2
|
||||||
datafile setAccess 3
|
ps.threshold 50
|
||||||
|
ps.threshold setAccess 2
|
||||||
|
ps.sttstep 5.000000
|
||||||
|
ps.sttstep setAccess 2
|
||||||
|
ps.sttend 50.000000
|
||||||
|
ps.sttend setAccess 2
|
||||||
|
ps.sttstart 10.000000
|
||||||
|
ps.sttstart setAccess 2
|
||||||
|
ps.omstep 5.000000
|
||||||
|
ps.omstep setAccess 2
|
||||||
|
ps.omend 20.000000
|
||||||
|
ps.omend setAccess 2
|
||||||
|
ps.omstart 10.000000
|
||||||
|
ps.omstart setAccess 2
|
||||||
|
ps.chistep 10.000000
|
||||||
|
ps.chistep setAccess 2
|
||||||
|
ps.chiend 150.000000
|
||||||
|
ps.chiend setAccess 2
|
||||||
|
ps.chistart 10.000000
|
||||||
|
ps.chistart setAccess 2
|
||||||
|
ps.phistep 5.000000
|
||||||
|
ps.phistep setAccess 2
|
||||||
|
ps.phiend 120.000000
|
||||||
|
ps.phiend setAccess 2
|
||||||
|
ps.phistart 10.000000
|
||||||
|
ps.phistart setAccess 2
|
||||||
|
hm3 CountMode timer
|
||||||
|
hm3 preset 10.000000
|
||||||
hm2 CountMode timer
|
hm2 CountMode timer
|
||||||
hm2 preset 5.000000
|
hm2 preset 5.000000
|
||||||
hm1 CountMode timer
|
hm1 CountMode timer
|
||||||
hm1 preset 5.000000
|
hm1 preset 5.000000
|
||||||
dbfile UNKNOWN
|
|
||||||
dbfile setAccess 2
|
|
||||||
# Motor th
|
|
||||||
th SoftZero 0.000000
|
|
||||||
th SoftLowerLim -120.000000
|
|
||||||
th SoftUpperLim 120.000000
|
|
||||||
th Fixed -1.000000
|
|
||||||
th sign 1.000000
|
|
||||||
th InterruptMode 0.000000
|
|
||||||
th AccessCode 2.000000
|
|
||||||
#Crystallographic Settings
|
#Crystallographic Settings
|
||||||
hkl lambda 1.179000
|
hkl lambda 1.179000
|
||||||
hkl setub 0.016169 0.011969 0.063195 -0.000545 0.083377 -0.009117 -0.162051 0.000945 0.006312
|
hkl setub 0.016169 0.011969 0.063195 -0.000545 0.083377 -0.009117 -0.162051 0.000945 0.006312
|
||||||
@ -148,8 +165,6 @@ twotheta InterruptMode 0.000000
|
|||||||
twotheta AccessCode 2.000000
|
twotheta AccessCode 2.000000
|
||||||
lastscancommand cscan a4 10. .1 10 5
|
lastscancommand cscan a4 10. .1 10 5
|
||||||
lastscancommand setAccess 2
|
lastscancommand setAccess 2
|
||||||
banana CountMode timer
|
|
||||||
banana preset 100.000000
|
|
||||||
sample_mur 0.000000
|
sample_mur 0.000000
|
||||||
sample_mur setAccess 2
|
sample_mur setAccess 2
|
||||||
email UNKNOWN
|
email UNKNOWN
|
||||||
|
Reference in New Issue
Block a user