- Fixed a few problems with hklscan
- Added transfer of zipped data to conman.c, histogram memory software in order to support the TRICS status display. - Upgraded TRICS data file writing. - First installment of triple axis spectrometer support: initialization of data structures and an implementation of the MAD dr(ive) command.
This commit is contained in:
282
tasinit.c
Normal file
282
tasinit.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
This is one implementation file for the TASMAD simulation module for
|
||||
SICS. The requirement is to make SICS look as much as TASMAD as
|
||||
possible. This includes:
|
||||
- TASMAD is variable driven
|
||||
- Sometimes variables are accessed in storage order.
|
||||
- A complicated calculation has to be done for getting the instruments
|
||||
settings right. The appropriate F77 routine from TASMAD will be
|
||||
reused.
|
||||
- The scan logic is different.
|
||||
- Output of ILL-formatted data files is required.
|
||||
|
||||
This file implements the initialization part of the whole thing.
|
||||
|
||||
Mark Koennecke, November 2000
|
||||
---------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "sicsvar.h"
|
||||
#include "counter.h"
|
||||
#include "motor.h"
|
||||
#include "tas.h"
|
||||
|
||||
/*
|
||||
As variables may be accessed in storage order, it is necessary to
|
||||
know the order of the motors
|
||||
*/
|
||||
extern char *tasMotorOrder[] = { "a1",
|
||||
"a2",
|
||||
"a3",
|
||||
"a4",
|
||||
"a5",
|
||||
"a6",
|
||||
"mcv",
|
||||
"sro",
|
||||
"ach",
|
||||
"mtl",
|
||||
"mtu",
|
||||
"stl",
|
||||
"stu",
|
||||
"stl",
|
||||
"atu",
|
||||
"mgl",
|
||||
"sgl",
|
||||
"sgu",
|
||||
"agl",
|
||||
NULL };
|
||||
/*
|
||||
In order to initialise the variable array in the TAS data structure we
|
||||
need to know the names of the variables in the right order. This order
|
||||
has to match the order defined in tas.h through the defines. Otherwise
|
||||
quite weird things may happen at runtime.
|
||||
*/
|
||||
extern char *tasVariableOrder[] = {
|
||||
"wav",
|
||||
"dm",
|
||||
"da",
|
||||
"etam",
|
||||
"etaa",
|
||||
"ti",
|
||||
"mn",
|
||||
"if1v",
|
||||
"if1h",
|
||||
"if2v",
|
||||
"if2h",
|
||||
"helm",
|
||||
"as",
|
||||
"bs",
|
||||
"cs",
|
||||
"aa",
|
||||
"bb",
|
||||
"cc",
|
||||
"etas",
|
||||
"ax",
|
||||
"ay",
|
||||
"az",
|
||||
"bx",
|
||||
"by",
|
||||
"bz",
|
||||
"ei",
|
||||
"ki",
|
||||
"ef",
|
||||
"kf",
|
||||
"qh",
|
||||
"qk",
|
||||
"ql",
|
||||
"en",
|
||||
"qm",
|
||||
"hx",
|
||||
"hy",
|
||||
"hz",
|
||||
"da1",
|
||||
"da2",
|
||||
"da3",
|
||||
"da4",
|
||||
"da5",
|
||||
"da6",
|
||||
"dmcv",
|
||||
"dsro",
|
||||
"dach",
|
||||
"dmtl",
|
||||
"dmtu",
|
||||
"dstl",
|
||||
"dstu",
|
||||
"datl",
|
||||
"datu",
|
||||
"dmgl",
|
||||
"dsgl",
|
||||
"dsgu",
|
||||
"dagl",
|
||||
"dei",
|
||||
"dki",
|
||||
"def",
|
||||
"dkf",
|
||||
"dqh",
|
||||
"dqk",
|
||||
"dql",
|
||||
"den",
|
||||
"dqm",
|
||||
"dt",
|
||||
"sm",
|
||||
"ss",
|
||||
"sa",
|
||||
"fx",
|
||||
"np",
|
||||
"f1",
|
||||
"f2",
|
||||
"lpa",
|
||||
"mrx1",
|
||||
"mrx2",
|
||||
"arx1",
|
||||
"arx2",
|
||||
NULL};
|
||||
/*---------------------------------------------------------------------
|
||||
There is a special feauture in MAD where the count mode is determined
|
||||
which variable, MN for monitor od TI for time has been set as the last
|
||||
one. In order to implement this in SICS callback functions will be
|
||||
used on the variables which switch the counter box into the appropriate
|
||||
mode.
|
||||
-----------------------------------------------------------------------*/
|
||||
static int MonitorCallback(int iEvent, void *pEvent, void *pUser)
|
||||
{
|
||||
pTASdata self = (pTASdata)pUser;
|
||||
assert(self);
|
||||
|
||||
if(iEvent != VALUECHANGE)
|
||||
return 0;
|
||||
|
||||
SetCounterMode(self->counter,ePreset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int TimerCallback(int iEvent, void *pEvent, void *pUser)
|
||||
{
|
||||
pTASdata self = (pTASdata)pUser;
|
||||
assert(self);
|
||||
|
||||
if(iEvent != VALUECHANGE)
|
||||
return 0;
|
||||
|
||||
SetCounterMode(self->counter,eTimer);
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------
|
||||
A function for killing the TAS data structure is needed
|
||||
-------------------------------------------------------------------------*/
|
||||
static void TASKill(void *pData)
|
||||
{
|
||||
pTASdata self = (pTASdata)pData;
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
if(self->pDes)
|
||||
DeleteDescriptor(self->pDes);
|
||||
free(self);
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
pTASdata pNew = NULL;
|
||||
int iPtr, iError;
|
||||
char pBueffel[132];
|
||||
pSicsVariable pVar = NULL;
|
||||
CommandList *pCom = NULL;
|
||||
|
||||
/* create a new data structure */
|
||||
pNew = (pTASdata)malloc(sizeof(TASdata));
|
||||
if(!pNew)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: insufficient memory to allocate TAS data structure",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pNew,0,sizeof(TASdata));
|
||||
pNew->pDes = CreateDescriptor("TAS");
|
||||
if(!pNew->pDes)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: insufficient memory to allocate TAS data structure",
|
||||
eError);
|
||||
free(pNew);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* connect to all the variables */
|
||||
iPtr = 0; iError = 0;
|
||||
while(tasVariableOrder[iPtr] != NULL)
|
||||
{
|
||||
pNew->tasPar[iPtr] = FindVariable(pSics,tasVariableOrder[iPtr]);
|
||||
if(!pNew->tasPar[iPtr])
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: TAS variable %s not found",
|
||||
tasVariableOrder[iPtr]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
iError++;
|
||||
}
|
||||
sprintf(pBueffel,"Initialised var %d", iPtr);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
iPtr++;
|
||||
}
|
||||
if(iError != 0)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: TAS bad initialisation, TAS not created",eError);
|
||||
TASKill(pNew);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* connect to the counter */
|
||||
pCom = FindCommand(pSics,"counter");
|
||||
if(!pCom)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: no neutron counter for TAS found",eError);
|
||||
TASKill(pNew);
|
||||
return 0;
|
||||
}
|
||||
pNew->counter = pCom->pData;
|
||||
|
||||
/*
|
||||
Install the callbacks for TI and MN. Sloppy error checking because
|
||||
the variables should have been accessed earlier on.
|
||||
*/
|
||||
pVar = FindVariable(pSics,"MN");
|
||||
if(pVar)
|
||||
{
|
||||
RegisterCallback(pVar->pCall,VALUECHANGE,MonitorCallback,pNew,NULL);
|
||||
}
|
||||
pVar = FindVariable(pSics,"TI");
|
||||
if(pVar)
|
||||
{
|
||||
RegisterCallback(pVar->pCall,VALUECHANGE,TimerCallback,pNew,NULL);
|
||||
}
|
||||
|
||||
/* install TAS commands */
|
||||
iError = AddCommand(pSics,"dr",TASDrive,TASKill,pNew);
|
||||
if(!iError)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: duplicate dr command not created",eError);
|
||||
TASKill(pNew);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
iError = AddCommand(pSics,"sc",TASScan,NULL,pNew);
|
||||
if(!iError)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: duplicate sc command not created",eError);
|
||||
TASKill(pNew);
|
||||
return 0;
|
||||
}
|
||||
iError = AddCommand(pSics,"set",TASSet,NULL,pNew);
|
||||
if(!iError)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: duplicate set command not created",eError);
|
||||
TASKill(pNew);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user