- Rearranged directory structure for forking out ANSTO
- Refactored site specific stuff into a site module - PSI specific stuff is now in the PSI directory. - The old version has been tagged with pre-ansto
This commit is contained in:
919
amorstat.c
Normal file
919
amorstat.c
Normal file
@ -0,0 +1,919 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
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("Collapsed maximum: %d\n",iMax);
|
||||
*/
|
||||
if(status != 1)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: histogram memory refused to Collapse",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
/*-----------------------------------------------------------------
|
||||
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
|
||||
{
|
||||
/*
|
||||
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;
|
||||
|
||||
/* get histogram dimensions */
|
||||
GetHistDim(self->pHM,iDim,&i3);
|
||||
fTime = GetHistTimeBin(self->pHM,&nTime);
|
||||
iDim[i3] = nTime;
|
||||
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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user