Files
sicspsi/amorstat.c
2007-09-05 11:16:22 +00:00

1127 lines
31 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
An additional projection mode: onto the y -tof plane was added
Mark Koennecke, June 2005
Support for new HTTP HM added
Mark Koennecke, July 2006
--------------------------------------------------------------------------*/
#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"
/*-------------------------------------------------------------------
Manually from SinqHM_def.h
--------------------------------------------------------------------*/
#define PROJECT__FRAME 0x0005
#define PROJECT__AMOR 0x0006
/*-------------------------------------------------------------------------
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,
commandContext cc)
{
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 */
SCPushContext2(pCon,cc);
SCWrite(pCon,"TOFClear",eError);
SCWriteUUencoded(pCon,"arrowaxis_time",iTime,
(iLength+1)*sizeof(int));
SCPopContext(pCon);
free(iTime);
}
return 1;
}
/*-------------------------------------------------------------------------*/
static int ScanStartCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{
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 */
SCPushContext2(pCon,cc);
SCWrite(pCon,"SCANClear",eError);
SCWriteUUencoded(pCon,pBueffel,iAxis,
(iLength+1)*sizeof(int));
SCPopContext(pCon);
free(iAxis);
free(fAxis);
}
return 1;
}
/*------------------------------------------------------------------------*/
static int ScanPointCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{
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 */
SCPushContext2(pCon,cc);
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 */
SCPopContext(pCon);
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);
}
return 0;
}
/*------------------------------------------------------------------------*/
static int LoadCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{
pAmorStat pAS = NULL;
SConnection *pCon = NULL;
if(iEvent == FILELOADED)
{
pAS = (pAmorStat)pEvent;
pCon = (SConnection *)pUser;
assert(pAS);
assert(pCon);
SCPushContext2(pCon,cc);
SendLoadedData(pAS,pCon);
SCPopContext(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;
commandContext comCon;
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.
*/
comCon = SCGetContext(pCon);
/* file load callback */
lID = RegisterCallback(self->pCall, comCon,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,comCon,SCANSTART,ScanStartCallback,
pCon, NULL);
SCRegister(pCon,pServ->pSics,pCall,lID);
lID = RegisterCallback(pCall,comCon,SCANPOINT,ScanPointCallback,
pCon, NULL);
SCRegister(pCon,pServ->pSics,pCall,lID);
lID = RegisterCallback(pCall,comCon,SCANEND,ScanPointCallback,
pCon, NULL);
SCRegister(pCon,pServ->pSics,pCall,lID);
if(iTOF == 0)
{
ScanStartCallback(SCANSTART,pDum,pCon,SCGetContext(pCon));
ScanPointCallback(SCANPOINT,pDum,pCon,SCGetContext(pCon));
}
}
/*
* histmem
*/
pDum = (pDummy)self->pHM;
pCall = pDum->pDescriptor->GetInterface(pDum,CALLBACKINTERFACE);
if(pCall)
{
lID = RegisterCallback(pCall,comCon,COUNTSTART,HMCountStartCallback,
pCon, NULL);
SCRegister(pCon,pServ->pSics,pCall,lID);
if(iTOF == 1)
{
HMCountStartCallback(COUNTSTART,pDum,pCon,SCGetContext(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;
char hmCommand[256];
HistInt *data = NULL;
/* 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("Collapsed maximum: %d\n",iMax);
*/
if(status != 1)
{
SCWrite(pCon,"ERROR: histogram memory refused to Collapse",eError);
return 0;
}
}
else if(self->iHTTP == 1)
{
if(i3 > 2){
snprintf(hmCommand,255,"sum:2:0:%d",iDim[2]);
if(self->pHM->pDriv->SubSample != NULL){
data = self->pHM->pDriv->SubSample(self->pHM->pDriv,pCon,0,hmCommand);
} else {
data = NULL;
}
if(data == NULL)
{
SCWrite(pCon,"ERROR: failed to retrieve collapsed data from HM", eError);
return 0;
}
for(i = 2; i < length; i++)
{
iImage[i] = htonl(data[i-1]);
}
free(data);
} else {
GetHistogramDirect(self->pHM,pCon,0,0,length-2,
&iImage[2], length*sizeof(HistInt));
for(i = 2; i < length; i++)
{
iImage[i] = htonl(iImage[i]);
}
}
}
else
{
/*
we are in simulation and just create 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());
/* iImage[iIdx+2] = htonl(77);*/
}
}
}
/* send image */
SCWriteUUencoded(pCon,"arrow_image",iImage,
((iDim[0]*iDim[1])+2)*sizeof(int));
free(iImage);
return 1;
}
/*-----------------------------------------------------------------
projectYTOF creates a 2D image from the detector by summing all x channels
together onto the y - tof plane
*/
static int projectYTOF(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;
char hmCommand[256];
HistInt *data = NULL;
/* get size of our problem */
GetHistDim(self->pHM,iDim,&i3);
if(i3 < 3 || iDim[2] < 2){
SCWrite(pCon,"ERROR: cannot project on Y - TOF, not in TOF mode", eError);
return 0;
}
/* allocate some data */
length = 2 + iDim[1]*iDim[2];
iImage = (int *)malloc(length*sizeof(int));
if(iImage == NULL)
{
SCWrite(pCon,"ERROR: failed to allocate memory in projectYTOF",eError);
return 0;
}
memset(iImage,0,(2 + iDim[1]*iDim[2])*sizeof(int));
/* first two numbers are the dimensions of the image */
iImage[0] = htonl(iDim[1]);
iImage[1] = htonl(iDim[2]);
if(isSINQHMDriv(self->pHM->pDriv))
{
/*
send a Project request to the histogram memory
*/
pTata = (SinqHMDriv *)self->pHM->pDriv->pPriv;
pHist = (pSINQHM)pTata->pMaster;
status = SINQHMProject(pHist, PROJECT__AMOR, 0, 0,
0, 0, iImage+2, (length-2)*sizeof(int));
for(i = 2; i < length; i++)
{
iImage[i] = htonl(iImage[i]);
}
if(status != 1)
{
SCWrite(pCon,"ERROR: histogram memory refused to project",eError);
return 0;
}
}
else if(self->iHTTP == 1)
{
snprintf(hmCommand,255,"sum:0:0:%d", iDim[0]);
data = self->pHM->pDriv->SubSample(self->pHM->pDriv,pCon,0,hmCommand);
if(data == NULL)
{
SCWrite(pCon,"ERROR: failed to retrieve Y-projection from HM", eError);
return 0;
}
for(i = 2; i < length; i++)
{
iImage[i] = htonl(data[i-1]);
}
free(data);
}
else
{
/*
we are in simulation and just create some random numbers
*/
for(i = 0; i < iDim[1]; i++)
{
for(i2 = 0; i2 < iDim[2]; i2++)
{
iIdx = i*iDim[2] + i2;
iImage[iIdx+2] = htonl(random());
iImage[iIdx+2] = htonl(77);
}
}
}
/* send image */
SCWriteUUencoded(pCon,"y_tof_projection",iImage,
((iDim[1]*iDim[2])+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, nTime;
pSINQHM pHist;
SinqHMDriv *pTata;
int iMax = -999999;
const float *timebin;
HistInt *iData = NULL;
int iStart;
/* get size of our problem */
GetHistDim(self->pHM,iDim,&i3);
/* allocate some data */
timebin = GetHistTimeBin(self->pHM, &nTime);
if(nTime < 2) {
return 1;
}
length = 1 + 2*nTime;
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(nTime);
if(isSINQHMDriv(self->pHM->pDriv))
{
iStart = iDim[0]*iDim[1]*nTime;
GetHistogramDirect(self->pHM,pCon,0,iStart,
iStart + 2*nTime,&iData[1],2*nTime*sizeof(HistInt));
for(i = 1; i < length; i++)
{
iData[i] = htonl(iData[i]);
}
}
else if(self->iHTTP == 1)
{
GetHistogramDirect(self->pHM,pCon,1,0,2*nTime,&iData[1],2*nTime*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,
(nTime+1)*sizeof(int));
iData[nTime] = htonl(nTime);
SCWriteUUencoded(pCon,"SING2",&iData[nTime],
(nTime+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, nTime;
char pBueffel[132];
pSINQHM pHist;
SinqHMDriv *pTata;
const float *fTime;
char hmCommand[256];
HistInt *data = NULL;
/* get histogram dimensions */
GetHistDim(self->pHM,iDim,&i3);
fTime = GetHistTimeBin(self->pHM,&nTime);
iDim[i3] = nTime;
i3++;
/* 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 if(self->iHTTP == 1)
{
snprintf(hmCommand,255,"sample:%d:%d:%d:%d:0:%d;sum:0:0:%d;sum:0:0:%d",
x1,x2,y1,y2,iDim[2]-1,x2-x1,y2-y1);
data = self->pHM->pDriv->SubSample(self->pHM->pDriv,pCon,0,hmCommand);
if(data == NULL)
{
SCWrite(pCon,"ERROR: failed to retrieve sub sampled data fromHM", eError);
return 0;
}
for(i = 1; i < iDim[2]+1; i++)
{
iSum[i] = htonl(data[i-1]);
}
free(data);
}
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],"projectytof") == 0)
{
iRet = projectYTOF(self,pCon);
if(iRet)
{
SCSendOK(pCon);
}
return iRet;
}
else if(strcmp(argv[1],"http") == 0)
{
if(argc > 2){
if(!SCMatchRights(pCon,usMugger)){
return 0;
}
self->iHTTP = atoi(argv[2]);
SCSendOK(pCon);
return 1;
} else {
snprintf(pBueffel,511,"amorstat.http = %d", self->iHTTP);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
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,SCGetContext(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;
}