- A couple of TAS fixes - o2t was fixed to work with any drivable - FOCUS was mended to include beam monitor in data file
910 lines
25 KiB
C
910 lines
25 KiB
C
/*--------------------------------------------------------------------------
|
|
A M O R S T A T U S
|
|
|
|
The implementation file for the amor status display facilitator module. The
|
|
reflectometer AMOR needs some advanced feautures for its status display.
|
|
These needs are taken care of here.
|
|
|
|
copyright: see copyright.h
|
|
|
|
Mark Koennecke, September 1999
|
|
|
|
As AMOR's histogram memory becomes too big in tof mode to transfer it
|
|
for status information the collapse and subsample functionalities have
|
|
been moved to the histogram memory. This code had to be modified to
|
|
call SINQHMProject directly.
|
|
|
|
Mark Koennecke, August 2001
|
|
--------------------------------------------------------------------------*/
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <tcl.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "counter.h"
|
|
#include "stringdict.h"
|
|
#include "HistMem.h"
|
|
#include "HistMem.i"
|
|
#include "HistDriv.i"
|
|
#include "hardsup/sinqhm.h"
|
|
#include "sinqhmdriv.i"
|
|
#include "scan.h"
|
|
#include "lld.h"
|
|
#include "amorstat.i"
|
|
#include "amorstat.h"
|
|
/*-------------------------------------------------------------------------
|
|
A static which determines if we are in TOF or scan mode.
|
|
*/
|
|
static int iTOF = 0;
|
|
static pHistMem pHMHM = NULL;
|
|
/*-------------------------------------------------------------------------*/
|
|
static int HMCountStartCallback(int iEvent, void *pEvent, void *pUser)
|
|
{
|
|
SConnection *pCon = (SConnection *)pUser;
|
|
const float *fTime = NULL;
|
|
int *iTime = NULL;
|
|
int iLength, iRet, i;
|
|
|
|
assert(pCon);
|
|
|
|
if(iEvent == COUNTSTART)
|
|
{
|
|
/* send current time binning */
|
|
iTOF = 1;
|
|
fTime = GetHistTimeBin(pHMHM,&iLength);
|
|
iTime = (int *)malloc((iLength+1)*sizeof(int));
|
|
if( (!fTime) || (!iTime))
|
|
{
|
|
return 0;
|
|
}
|
|
iTime[0] = htonl(iLength);
|
|
for(i = 0 ; i < iLength; i++)
|
|
{
|
|
iTime[i+1] = htonl((int)((fTime[i]/10.)*65536.));
|
|
}
|
|
/* send new time binning to all clients */
|
|
SCWrite(pCon,"TOFClear",eError);
|
|
SCWriteUUencoded(pCon,"arrowaxis_time",iTime,
|
|
(iLength+1)*sizeof(int));
|
|
free(iTime);
|
|
}
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int ScanStartCallback(int iEvent, void *pEvent, void *pUser)
|
|
{
|
|
float *fAxis = NULL;
|
|
int *iAxis = NULL;
|
|
int iLength, iRet, i;
|
|
char pBueffel[80], pName[40];
|
|
SConnection *pCon = (SConnection *)pUser;
|
|
pScanData pScan = (pScanData)pEvent;
|
|
|
|
assert(pCon);
|
|
assert(pScan);
|
|
|
|
|
|
if(iEvent == SCANSTART)
|
|
{
|
|
iTOF = 0;
|
|
/* send current axis */
|
|
iLength = GetScanNP(pScan);
|
|
fAxis = (float *)malloc((iLength+1)*sizeof(float));
|
|
iAxis = (int *)malloc((iLength+1)*sizeof(int));
|
|
if( (!fAxis) || (!iAxis))
|
|
{
|
|
return 0;
|
|
}
|
|
iAxis[0] = htonl(iLength);
|
|
GetSoftScanVar(pScan,0,fAxis,iLength);
|
|
GetScanVarName(pScan,0,pName,39);
|
|
sprintf(pBueffel,"arrowaxis_%s",pName);
|
|
for(i = 0 ; i < iLength; i++)
|
|
{
|
|
iAxis[i+1] = htonl((int)(fAxis[i]*65536.));
|
|
}
|
|
/* send new axis to client */
|
|
SCWrite(pCon,"SCANClear",eError);
|
|
SCWriteUUencoded(pCon,pBueffel,iAxis,
|
|
(iLength+1)*sizeof(int));
|
|
free(iAxis);
|
|
free(fAxis);
|
|
}
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int ScanPointCallback(int iEvent, void *pEvent, void *pUser)
|
|
{
|
|
long *lData = NULL;
|
|
int *iData = NULL;
|
|
int iLength, iRet, i;
|
|
SConnection *pCon = (SConnection *)pUser;
|
|
pScanData pScan = (pScanData)pEvent;
|
|
|
|
assert(pCon);
|
|
assert(pScan);
|
|
|
|
|
|
if( (iEvent == SCANPOINT) || (iEvent == SCANEND) )
|
|
{
|
|
/* send current data */
|
|
iTOF = 0;
|
|
iLength = GetScanNP(pScan);
|
|
lData = (long *)malloc((iLength+1)*sizeof(long));
|
|
iData = (int *)malloc((iLength+1)*sizeof(int));
|
|
if( (!lData) || (!iData))
|
|
{
|
|
return 0;
|
|
}
|
|
iData[0] = htonl(iLength);
|
|
GetScanCounts(pScan,lData,iLength);
|
|
for(i = 0 ; i < iLength; i++)
|
|
{
|
|
iData[i+1] = htonl((int)(lData[i]));
|
|
}
|
|
/* send counts to client */
|
|
SCWriteUUencoded(pCon,"arrow_spinupup",iData,
|
|
(iLength+1)*sizeof(int));
|
|
/* send counts for other detector */
|
|
GetScanMonitor(pScan,2,lData,iLength);
|
|
for(i = 0 ; i < iLength; i++)
|
|
{
|
|
iData[i+1] = htonl((int)(lData[i]));
|
|
}
|
|
SCWriteUUencoded(pCon,"arrow_spinuplo",iData,
|
|
(iLength+1)*sizeof(int));
|
|
/* to do: check for polarization and send spinlo */
|
|
free(iData);
|
|
free(lData);
|
|
}
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int SendLoadedData(pAmorStat self, SConnection *pCon)
|
|
{
|
|
int i, iRet, *iData = NULL;
|
|
char pBueffel[80];
|
|
UserData ud;
|
|
|
|
SCWrite(pCon,"loaded_CLEAR",eValue);
|
|
iRet = LLDnodePtr2First(self->iUserList);
|
|
while(iRet != 0)
|
|
{
|
|
LLDnodeDataTo(self->iUserList,&ud);
|
|
iData = (int *)malloc((ud.iNP*2 + 1)*sizeof(int));
|
|
if(!iData)
|
|
{
|
|
return 0;
|
|
}
|
|
iData[0] = htonl(ud.iNP);
|
|
for(i = 0; i < ud.iNP; i++)
|
|
{
|
|
iData[i+1] = htonl((int)(ud.fX[i]*65536));
|
|
iData[i+1+ud.iNP] = htonl((int)(ud.fY[i]*65536));
|
|
}
|
|
sprintf(pBueffel,"loaded_%s",ud.name);
|
|
SCWriteUUencoded(pCon,pBueffel,iData,(ud.iNP*2+1)*sizeof(int));
|
|
iRet = LLDnodePtr2Next(self->iUserList);
|
|
}
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int LoadCallback(int iEvent, void *pEvent, void *pUser)
|
|
{
|
|
pAmorStat pAS = NULL;
|
|
SConnection *pCon = NULL;
|
|
|
|
if(iEvent == FILELOADED)
|
|
{
|
|
pAS = (pAmorStat)pEvent;
|
|
pCon = (SConnection *)pUser;
|
|
assert(pAS);
|
|
assert(pCon);
|
|
SendLoadedData(pAS,pCon);
|
|
}
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static void ClearUserData(pAmorStat self)
|
|
{
|
|
int iRet;
|
|
UserData ud;
|
|
|
|
iRet = LLDnodePtr2First(self->iUserList);
|
|
while(iRet != 0)
|
|
{
|
|
LLDnodeDataTo(self->iUserList,&ud);
|
|
if(ud.fX != NULL)
|
|
free(ud.fX);
|
|
if(ud.fY != NULL)
|
|
free(ud.fY);
|
|
if(ud.name != NULL)
|
|
free(ud.name);
|
|
iRet = LLDnodePtr2Next(self->iUserList);
|
|
}
|
|
LLDdelete(self->iUserList);
|
|
self->iUserList = LLDcreate(sizeof(UserData));
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
void KillAmorStatus(void *pData)
|
|
{
|
|
pAmorStat self = (pAmorStat)pData;
|
|
|
|
if(!self)
|
|
return;
|
|
|
|
if(self->iUserList >= 0)
|
|
{
|
|
ClearUserData(self);
|
|
LLDdelete(self->iUserList);
|
|
}
|
|
if(self->pDes)
|
|
DeleteDescriptor(self->pDes);
|
|
if(self->pCall)
|
|
DeleteCallBackInterface(self->pCall);
|
|
free(self);
|
|
}
|
|
/*------------------------------------------------------------------*/
|
|
int AmorStatusFactory(SConnection *pCon, SicsInterp *pSics,
|
|
void *pData, int argc, char *argv[])
|
|
{
|
|
pAmorStat pNew = NULL;
|
|
CommandList *pCom = NULL;
|
|
char pBueffel[256];
|
|
int iRet;
|
|
|
|
/* check number of arguments */
|
|
if(argc < 4)
|
|
{
|
|
sprintf(pBueffel,"ERROR: insufficient number of arguments to %s",
|
|
argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
|
|
/* allocate a new data structure */
|
|
pNew = (pAmorStat)malloc(sizeof(AmorStat));
|
|
if(!pNew)
|
|
{
|
|
sprintf(pBueffel,"ERROR: out of memory in %s",argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
memset(pNew,0,sizeof(AmorStat));
|
|
pNew->pDes = CreateDescriptor("AmorStatus");
|
|
pNew->iUserList = LLDcreate(sizeof(UserData));
|
|
pNew->pCall = CreateCallBackInterface();
|
|
if( (!pNew->pDes) || (pNew->iUserList < 0) || (!pNew->pCall) )
|
|
{
|
|
sprintf(pBueffel,"ERROR: out of memory in %s",argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
KillAmorStatus(pNew);
|
|
return 0;
|
|
}
|
|
|
|
/* to locate the HM and the scan object */
|
|
pCom = FindCommand(pSics,argv[2]);
|
|
if(pCom)
|
|
{
|
|
if(pCom->pData)
|
|
{
|
|
if(!iHasType(pCom->pData,"ScanObject"))
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s is NO scan object",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
KillAmorStatus(pNew);
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s is NO scan object",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
KillAmorStatus(pNew);
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s NOT found",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
KillAmorStatus(pNew);
|
|
return 0;
|
|
}
|
|
pNew->pScan = (pScanData)pCom->pData;
|
|
pCom = FindCommand(pSics,argv[3]);
|
|
if(pCom)
|
|
{
|
|
if(pCom->pData)
|
|
{
|
|
if(!iHasType(pCom->pData,"HistMem"))
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s is NO histogram memory object",
|
|
argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
KillAmorStatus(pNew);
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s is NO histogram memory object",
|
|
argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
KillAmorStatus(pNew);
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s NOT found",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
KillAmorStatus(pNew);
|
|
return 0;
|
|
}
|
|
pNew->pHM = (pHistMem)pCom->pData;
|
|
pHMHM = (pHistMem)pCom->pData;
|
|
|
|
/* install command */
|
|
iRet = AddCommand(pSics,argv[1],
|
|
AmorStatusAction,KillAmorStatus,pNew);
|
|
if(!iRet)
|
|
{
|
|
sprintf(pBueffel,"ERROR: duplicate command %s NOT created",
|
|
argv[1]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
KillAmorStatus(pNew);
|
|
return 0;
|
|
}
|
|
|
|
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------*/
|
|
static int RegisterInterest(pAmorStat self, SConnection *pCon)
|
|
{
|
|
long lID;
|
|
pDummy pDum = NULL;
|
|
pICallBack pCall = NULL;
|
|
|
|
assert(self);
|
|
assert(pCon);
|
|
|
|
/* Register all the callbacks. Dependent on the state of
|
|
iTOF invoke the apropriate callbacks in order to force
|
|
an initial update.
|
|
*/
|
|
/* file load callback */
|
|
lID = RegisterCallback(self->pCall, FILELOADED, LoadCallback,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pServ->pSics, self->pCall,lID);
|
|
SendLoadedData(self,pCon);
|
|
|
|
/* scan object */
|
|
pDum = (pDummy)self->pScan;
|
|
pCall = pDum->pDescriptor->GetInterface(pDum,CALLBACKINTERFACE);
|
|
if(pCall)
|
|
{
|
|
lID = RegisterCallback(pCall,SCANSTART,ScanStartCallback,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pServ->pSics,pCall,lID);
|
|
lID = RegisterCallback(pCall,SCANPOINT,ScanPointCallback,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pServ->pSics,pCall,lID);
|
|
lID = RegisterCallback(pCall,SCANEND,ScanPointCallback,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pServ->pSics,pCall,lID);
|
|
if(iTOF == 0)
|
|
{
|
|
ScanStartCallback(SCANSTART,pDum,pCon);
|
|
ScanPointCallback(SCANPOINT,pDum,pCon);
|
|
}
|
|
}
|
|
pDum = (pDummy)self->pHM;
|
|
pCall = pDum->pDescriptor->GetInterface(pDum,CALLBACKINTERFACE);
|
|
if(pCall)
|
|
{
|
|
lID = RegisterCallback(pCall,COUNTSTART,HMCountStartCallback,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pServ->pSics,pCall,lID);
|
|
if(iTOF == 1)
|
|
{
|
|
HMCountStartCallback(COUNTSTART,pDum,pCon);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------*/
|
|
static int FileLoad(pAmorStat self, SConnection *pCon,
|
|
char *name, double dScale)
|
|
{
|
|
char pBueffel[256], pDummy[50];
|
|
FILE *fd = NULL;
|
|
UserData ud;
|
|
int iNP, i;
|
|
float fDummy;
|
|
|
|
/* open the file */
|
|
fd = fopen(name,"r");
|
|
if(!fd)
|
|
{
|
|
sprintf(pBueffel,"ERROR: cannot open %s for reading",name);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
|
|
/* skip first line */
|
|
if(fgets(pBueffel,255,fd) == NULL)
|
|
{
|
|
SCWrite(pCon,"ERROR: premature end of file",eError);
|
|
fclose(fd);
|
|
return 0;
|
|
}
|
|
|
|
/* read number of points in second line */
|
|
if(fgets(pBueffel,255,fd) == NULL)
|
|
{
|
|
SCWrite(pCon,"ERROR: premature end of file",eError);
|
|
fclose(fd);
|
|
return 0;
|
|
}
|
|
sscanf(pBueffel,"%s %d",pDummy, &iNP);
|
|
/* allocate data */
|
|
ud.iNP = iNP;
|
|
ud.fX = (float *)malloc(iNP*sizeof(float));
|
|
ud.fY = (float *)malloc(iNP*sizeof(float));
|
|
ud.name = strdup(name);
|
|
|
|
/* skip two lines */
|
|
if(fgets(pBueffel,255,fd) == NULL)
|
|
{
|
|
SCWrite(pCon,"ERROR: premature end of file",eError);
|
|
fclose(fd);
|
|
return 0;
|
|
}
|
|
if(fgets(pBueffel,255,fd) == NULL)
|
|
{
|
|
SCWrite(pCon,"ERROR: premature end of file",eError);
|
|
fclose(fd);
|
|
return 0;
|
|
}
|
|
|
|
/* loop reading data */
|
|
for(i = 0; i < iNP; i++)
|
|
{
|
|
if(fgets(pBueffel,255,fd) == NULL)
|
|
{
|
|
SCWrite(pCon,"WARNING: premature end of file",eError);
|
|
break;
|
|
}
|
|
sscanf(pBueffel," %f %f %f",&ud.fX[i],&fDummy, &ud.fY[i]);
|
|
ud.fY[i] *= dScale;
|
|
}
|
|
fclose(fd);
|
|
|
|
/* enter ud into list */
|
|
LLDnodeInsertFrom(self->iUserList,&ud);
|
|
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------
|
|
Collapse creates a 2D image from the detector by summing all time
|
|
channels together in any given detector.
|
|
*/
|
|
|
|
static int Collapse(pAmorStat self, SConnection *pCon)
|
|
{
|
|
HistInt *lData = NULL;
|
|
int i, i2, i3, iDim[MAXDIM], iIdx, iSum, status, length;
|
|
int *iImage = NULL, *iPtr;
|
|
pSINQHM pHist;
|
|
SinqHMDriv *pTata;
|
|
int iMax = -999999;
|
|
|
|
/* get size of our problem */
|
|
GetHistDim(self->pHM,iDim,&i3);
|
|
assert(i3 == 3);
|
|
|
|
/* allocate some data */
|
|
length = 2 + iDim[0]*iDim[1];
|
|
iImage = (int *)malloc(length*sizeof(int));
|
|
if(iImage == NULL)
|
|
{
|
|
SCWrite(pCon,"ERROR: failed to allocate memory in Collapse",eError);
|
|
return 0;
|
|
}
|
|
memset(iImage,0,(2 + iDim[0]*iDim[1])*sizeof(int));
|
|
|
|
/* first two numbers are the dimension of the image */
|
|
iImage[0] = htonl(iDim[0]);
|
|
iImage[1] = htonl(iDim[1]);
|
|
|
|
|
|
if(isSINQHMDriv(self->pHM->pDriv))
|
|
{
|
|
/*
|
|
send a Project request to the histogram memory
|
|
*/
|
|
pTata = (SinqHMDriv *)self->pHM->pDriv->pPriv;
|
|
pHist = (pSINQHM)pTata->pMaster;
|
|
/*
|
|
The 3 in the following call has to be identical to
|
|
PROJECT__COLL in sinqhm_def.h
|
|
*/
|
|
status = SINQHMProject(pHist, 3, 0, iDim[0],
|
|
0, iDim[1], iImage+2, (length-2)*sizeof(int));
|
|
/*
|
|
Byte swapping
|
|
*/
|
|
for(i = 2; i < length; i++)
|
|
{
|
|
/*
|
|
if(iImage[i] > iMax){
|
|
iMax = iImage[i];
|
|
}
|
|
*/
|
|
iImage[i] = htonl(iImage[i]);
|
|
}
|
|
/*
|
|
printf("Collpased maximum: %d\n",iMax);
|
|
*/
|
|
if(status != 1)
|
|
{
|
|
SCWrite(pCon,"ERROR: histogram memory refused to Collapse",eError);
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
we are in simulation and justcreate some random numbers
|
|
*/
|
|
for(i = 0; i < iDim[0]; i++)
|
|
{
|
|
for(i2 = 0; i2 < iDim[1]; i2++)
|
|
{
|
|
iIdx = i*iDim[1] + i2;
|
|
iImage[iIdx+2] = htonl(random());
|
|
}
|
|
}
|
|
}
|
|
|
|
/* send image */
|
|
SCWriteUUencoded(pCon,"arrow_image",iImage,
|
|
((iDim[0]*iDim[1])+2)*sizeof(int));
|
|
free(iImage);
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------
|
|
SendSingleTOF sends single detector data for TOF mode
|
|
*/
|
|
|
|
static int SendSingleTOF(pAmorStat self, SConnection *pCon)
|
|
{
|
|
HistInt *lData = NULL;
|
|
int i, i2, i3, iDim[MAXDIM], iIdx, iSum, status, length;
|
|
pSINQHM pHist;
|
|
SinqHMDriv *pTata;
|
|
int iMax = -999999;
|
|
const float *timebin;
|
|
HistInt *iData = NULL;
|
|
|
|
/* get size of our problem */
|
|
GetHistDim(self->pHM,iDim,&i3);
|
|
assert(i3 == 3);
|
|
|
|
/* allocate some data */
|
|
timebin = GetHistTimeBin(self->pHM, &i3);
|
|
length = 1 + 2*i3;
|
|
iData = (HistInt *)malloc(length*sizeof(HistInt));
|
|
if(iData == NULL){
|
|
SCWrite(pCon,"ERROR: failed to allocate memory in SendSingleTOF",
|
|
eError);
|
|
return 0;
|
|
}
|
|
memset(iData,0,length*sizeof(int));
|
|
|
|
/* first number is the length of each single histogram */
|
|
iData[0] = htonl(i3);
|
|
|
|
|
|
if(isSINQHMDriv(self->pHM->pDriv))
|
|
{
|
|
GetHistogramDirect(self->pHM,pCon,0,iDim[0]*iDim[1]*iDim[2],
|
|
2*iDim[2],&iData[1],2*iDim[2]*sizeof(HistInt));
|
|
for(i = 1; i < length; i++)
|
|
{
|
|
iData[i] = htonl(iData[i]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
we are in simulation and just create some random numbers
|
|
*/
|
|
for(i = 1; i < length; i++)
|
|
{
|
|
iData[i] = htonl(random());
|
|
}
|
|
}
|
|
|
|
/*
|
|
send, with a little trick to do two histograms.
|
|
*/
|
|
SCWriteUUencoded(pCon,"SING1",iData,
|
|
(iDim[2]+1)*sizeof(int));
|
|
iData[iDim[2]] = htonl(iDim[2]);
|
|
SCWriteUUencoded(pCon,"SING2",&iData[iDim[2]],
|
|
(iDim[2]+1)*sizeof(int));
|
|
free(iData);
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------
|
|
SubSample sums histogram data in the area defined by the rectangle
|
|
x1,y1 x2, y2. Summing is along the time axis.
|
|
*/
|
|
static int SubSample(pAmorStat self, SConnection *pCon,
|
|
char *name, int x1, int x2, int y1, int y2)
|
|
{
|
|
int iDim[MAXDIM], i, i2, i3, *iSum = NULL, iLang, *iPtr;
|
|
HistInt *lData = NULL;
|
|
int iLimit, status;
|
|
char pBueffel[132];
|
|
pSINQHM pHist;
|
|
SinqHMDriv *pTata;
|
|
|
|
/* get histogram dimensions */
|
|
GetHistDim(self->pHM,iDim,&i3);
|
|
assert(i3 == 3);
|
|
|
|
/* check limits */
|
|
if(x2 < x1){
|
|
i = x1;
|
|
x1 = x2;
|
|
x2 = i +1;
|
|
}
|
|
if(y2 < y1){
|
|
i = y1;
|
|
y1 = y2;
|
|
y2 = i + 1;
|
|
}
|
|
|
|
iLimit = 0;
|
|
if( x1 > iDim[0])
|
|
{
|
|
iLimit = 1;
|
|
x1 = iDim[0] - 1;
|
|
}
|
|
if(x1 < 0)
|
|
{
|
|
iLimit = 1;
|
|
x1 = 0;
|
|
}
|
|
if( x2 > iDim[0])
|
|
{
|
|
iLimit = 2;
|
|
x2 = iDim[0] - 1;
|
|
}
|
|
if(x2 < 0)
|
|
{
|
|
iLimit = 2;
|
|
x2 = 0;
|
|
}
|
|
if( y1 > iDim[1])
|
|
{
|
|
iLimit = 3;
|
|
y1 = iDim[1] - 1;
|
|
}
|
|
if(y1 < 0)
|
|
{
|
|
iLimit = 3;
|
|
y1 = 0;
|
|
}
|
|
if( y2 > iDim[1])
|
|
{
|
|
iLimit = 4;
|
|
y2 = iDim[1] - 1;
|
|
}
|
|
if(y2 < 0)
|
|
{
|
|
iLimit = 4;
|
|
y2 = 0;
|
|
}
|
|
if(iLimit != 0)
|
|
{
|
|
switch(iLimit)
|
|
{
|
|
case 1:
|
|
strcpy(pBueffel,"WARNING: limit violation on x1");
|
|
break;
|
|
case 2:
|
|
strcpy(pBueffel,"WARNING: limit violation on x2");
|
|
break;
|
|
case 3:
|
|
strcpy(pBueffel,"WARNING: limit violation on y1");
|
|
break;
|
|
case 4:
|
|
strcpy(pBueffel,"WARNING: limit violation on y2");
|
|
break;
|
|
}
|
|
SCWrite(pCon,pBueffel,eWarning);
|
|
}
|
|
|
|
/* allocate space for result */
|
|
iSum = (int *)malloc((iDim[2]+1)*sizeof(int));
|
|
if(!iSum)
|
|
{
|
|
SCWrite(pCon,"ERROR: out of memory in SubSample",eError);
|
|
return 0;
|
|
}
|
|
memset(iSum,0,(iDim[2]+1)*sizeof(int));
|
|
|
|
iSum[0] = htonl(iDim[2]);
|
|
if(isSINQHMDriv(self->pHM->pDriv))
|
|
{
|
|
/*
|
|
send project message to histogram memory
|
|
*/
|
|
pTata = (SinqHMDriv *)self->pHM->pDriv->pPriv;
|
|
pHist = (pSINQHM)pTata->pMaster;
|
|
status = SINQHMProject(pHist, 4, x1, x2-x1,
|
|
y1, y2-y1, iSum+1, iDim[2]*sizeof(int));
|
|
/*
|
|
convert to network byte order
|
|
*/
|
|
for(i = 1; i < iDim[2]+1; i++)
|
|
{
|
|
iSum[i] = htonl(iSum[i]);
|
|
}
|
|
if(status != 1)
|
|
{
|
|
SCWrite(pCon,"ERROR: histogram memory refused to SubSample",eError);
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* do acouple of random numbers! */
|
|
for(i = 1; i < iDim[2]+1; i++)
|
|
{
|
|
iSum[i] = htonl(random());
|
|
}
|
|
}
|
|
|
|
/* send */
|
|
sprintf(pBueffel,"arrowsum_%s",name);
|
|
SCWriteUUencoded(pCon,pBueffel,iSum,(iDim[2]+1)*sizeof(int));
|
|
|
|
free(iSum);
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------*/
|
|
int AmorStatusAction(SConnection *pCon, SicsInterp *pSics,
|
|
void *pData, int argc, char *argv[])
|
|
{
|
|
pAmorStat self = (pAmorStat)pData;
|
|
char pBueffel[512];
|
|
double dScale;
|
|
int iRet;
|
|
int x1, x2, y1, y2;
|
|
|
|
assert(self);
|
|
|
|
if(argc < 2)
|
|
{
|
|
sprintf(pBueffel,"ERROR: need argument to %s",argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
|
|
strtolower(argv[1]);
|
|
if(strcmp(argv[1],"interest") == 0)
|
|
{
|
|
RegisterInterest(self,pCon);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
else if(strcmp(argv[1],"load") == 0)
|
|
{
|
|
if(argc < 4)
|
|
{
|
|
sprintf(pBueffel,
|
|
"ERROR: need filename and scale argument to %s load",
|
|
argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetDouble(pSics->pTcl,argv[3],&dScale);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: cannot convert %s to scale factor",
|
|
argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
FileLoad(self,pCon,argv[2],dScale);
|
|
InvokeCallBack(self->pCall, FILELOADED,self);
|
|
SCSendOK(pCon);
|
|
}
|
|
else if(strcmp(argv[1],"collapse") == 0)
|
|
{
|
|
iRet = Collapse(self,pCon);
|
|
if(iRet)
|
|
{
|
|
SCSendOK(pCon);
|
|
}
|
|
return iRet;
|
|
}
|
|
else if(strcmp(argv[1],"sample") == 0)
|
|
{
|
|
if(argc < 7)
|
|
{
|
|
SCWrite(pCon,"ERROR: insufficent number of arguments to sample",
|
|
eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(pSics->pTcl,argv[3],&x1);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: cannot convert %s to int", argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(pSics->pTcl,argv[6],&y2);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: cannot convert %s to int", argv[6]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(pSics->pTcl,argv[4],&x2);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: cannot convert %s to int", argv[4]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(pSics->pTcl,argv[5],&y1);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: cannot convert %s to int", argv[5]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = SubSample(self,pCon,argv[2],x1,x2,y1,y2);
|
|
if(iRet)
|
|
SCSendOK(pCon);
|
|
return iRet;
|
|
}
|
|
else if(strcmp(argv[1],"singletof") == 0)
|
|
{
|
|
return SendSingleTOF(self,pCon);
|
|
}
|
|
else if(strcmp(argv[1],"sendloaded") == 0)
|
|
{
|
|
SendLoadedData(self,pCon);
|
|
return 1;
|
|
}
|
|
else if(strcmp(argv[1],"clear") == 0)
|
|
{
|
|
ClearUserData(self);
|
|
InvokeCallBack(self->pCall, FILELOADED,self);
|
|
SCSendOK(pCon);
|
|
}
|
|
else if(strcmp(argv[1],"tofmode") == 0)
|
|
{
|
|
HMCountStartCallback(COUNTSTART,NULL,pCon);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s nor recognized as subcommand to %s",
|
|
argv[1], argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|