Files
sicspsi/amorstat.c
koennecke 1e9f9d408c - Introduced a command history log for statistical and
syntax checking input purposes
- Rectified an error message in fourmess.c
- HMcontrol did not check for the HM to stop before returning. This
  caused weird data files at AMOR as the data had not yet been downloaded
  from the HM.
- Fixed an issue about parameters in multicounter
- Temporary fix in nxscript.c to always read the Hm from the HM and not
  a buffer. This is prior to rethinking caching strategies for old style
  HM's.
- Synchronize now copies fixed motors correctly. This used to cause
  irritation with users. This now requires a script syncdrive to exist
  in the sync server which takes care of handling the fixed flag when
  this is desired.
- Added initify to sicsdata in order to copy large value timebins over
  properly at AMOR
2010-06-01 10:01:01 +00:00

1037 lines
28 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
Lightly ammended for the new second generation HM module.
Mark koennecke, May 2009
--------------------------------------------------------------------------*/
#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"
#include "sicshipadaba.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)
{
SConnection *pCon = (SConnection *) pUser;
const float *fTime = NULL;
int *iTime = NULL;
int iLength, iRet, i;
pHdb tbin = NULL;
/* check kill condition */
if (pCon == NULL || !SCisConnected(pCon)) {
return -1;
}
if (iEvent == COUNTSTART) {
/* send current time binning */
iTOF = 1;
if(pHMHM->pDes->parNode != NULL){
tbin = GetHipadabaNode(pHMHM->pDes->parNode,"time_binning");
assert(tbin != NULL);
iLength = tbin->value.arrayLength;
iTime = (int *) malloc((iLength + 1) * sizeof(int));
if ((!iTime)) {
return 0;
}
iTime[0] = htonl(iLength);
for (i = 0; i < iLength; i++) {
iTime[i + 1] = htonl( (int) ( (tbin->value.v.floatArray[i]) / 10.) * 65536.) ;
}
} else {
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(pScan);
/* check kill conditions */
if (pCon == NULL || !SCisConnected(pCon)) {
return -1;
}
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(pScan);
/* check kill conditions */
if (pCon == NULL || !SCisConnected(pCon)) {
return -1;
}
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);
}
return 0;
}
/*------------------------------------------------------------------------*/
static int LoadCallback(int iEvent, void *pEvent, void *pUser)
{
pAmorStat pAS = NULL;
SConnection *pCon = NULL;
pCon = (SConnection *) pUser;
/* check kill conditions */
if (pCon == NULL || !SCisConnected(pCon)) {
return -1;
}
if (iEvent == FILELOADED) {
pAS = (pAmorStat) pEvent;
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") && !iHasType(pCom->pData,"HistMemSec")) {
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,
SCCopyConnection(pCon), SCDeleteConnection);
SendLoadedData(self, pCon);
/* scan object */
pDum = (pDummy) self->pScan;
pCall = pDum->pDescriptor->GetInterface(pDum, CALLBACKINTERFACE);
if (pCall) {
lID = RegisterCallback(pCall, SCANSTART, ScanStartCallback,
SCCopyConnection(pCon), SCDeleteConnection);
lID = RegisterCallback(pCall, SCANPOINT, ScanPointCallback,
SCCopyConnection(pCon), SCDeleteConnection);
lID = RegisterCallback(pCall, SCANEND, ScanPointCallback,
SCCopyConnection(pCon), SCDeleteConnection);
if (iTOF == 0) {
ScanStartCallback(SCANSTART, pDum, pCon);
ScanPointCallback(SCANPOINT, pDum, pCon);
}
}
/*
* histmem
*/
pDum = (pDummy) self->pHM;
pCall = pDum->pDescriptor->GetInterface(pDum, CALLBACKINTERFACE);
if (pCall) {
lID = RegisterCallback(pCall, COUNTSTART, HMCountStartCallback,
SCCopyConnection(pCon), SCDeleteConnection);
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;
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);
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;
}