AngularConversion splitted in a static file and in one file dependent on slsDetectorBase

git-svn-id: file:///afs/psi.ch/project/sls_det_software/svn/slsDetectorSoftware@240 951219d9-93cf-4727-9268-0efd64621fa3
This commit is contained in:
bergamaschi 2012-09-05 10:12:49 +00:00
parent ca75754b83
commit 6b34cb8e71
14 changed files with 1636 additions and 380 deletions

View File

@ -9,11 +9,11 @@ INCLUDES= -IcommonFiles -IslsDetector -IMySocketTCP -IusersFunctions -ImultiSlsD
CC=g++ CC=g++
SRC_CLNT= slsDetectorAnalysis/fileIO.cpp MySocketTCP/MySocketTCP.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp SRC_CLNT= slsDetectorAnalysis/fileIO.cpp MySocketTCP/MySocketTCP.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/angularConversionStatic.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp
OBJS = $(SRC_CLNT:.cpp=.o) OBJS = $(SRC_CLNT:.cpp=.o)
HEADERS = $(SRC_CLNT:.cpp=.h) commonFiles/sls_detector_defs.h slsDetectorAnalysis/detectorData.h slsDetector/slsDetectorBase.h slsDetector/slsDetectorUsers.h multiSlsDetector/multiSlsDetectorCommand.h slsDetectorAnalysis/enCalLogClass.h slsDetectorAnalysis/angCalLogClass.h HEADERS = $(SRC_CLNT:.cpp=.h) commonFiles/sls_detector_defs.h slsDetectorAnalysis/detectorData.h slsDetector/slsDetectorBase.h slsDetector/slsDetectorUsers.h multiSlsDetector/multiSlsDetectorCommand.h slsDetectorAnalysis/enCalLogClass.h slsDetectorAnalysis/angCalLogClass.h slsDetectorAnalysis/angleConversionConstant.h usersFunctions/angleFunction.h

View File

@ -3,9 +3,15 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#ifdef __CINT__
#define MYROOT
#endif
#ifndef MYROOT
#include "slsDetectorCommand.h" #include "slsDetectorCommand.h"
#include "slsDetectorUtils.h" #include "slsDetectorUtils.h"
#include "sls_detector_defs.h" #include "sls_detector_defs.h"
#endif
using namespace std; using namespace std;
@ -15,45 +21,128 @@ class angCalLogClass {
public: public:
angCalLogClass(slsDetectorUtils *det){ \ #ifndef MYROOT
char cmd[1000]; angCalLogClass(slsDetectorUtils *det){ createVars();
char cmd[1000]; \
char *argv[2]; \ char *argv[2]; \
argv[0]=cmd; \ argv[0]=cmd; \
sprintf(cmd,"_%d.angcal",det->getFileIndex()); \ sprintf(cmd,"_%d.angcal",det->getFileIndex()); \
outfile.open(string(det->getFilePath()+string("/")+det->getFileName()+string(cmd)).c_str()); \ outfile.open(string(det->getFilePath()+string("/")+det->getFileName()+string(cmd)).c_str()); \
myDet=new slsDetectorCommand(det); \ myDet=new slsDetectorCommand(det); \
strcpy(cmd,"type"); \ if (outfile.is_open()) { \
outfile << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \ for (int iv=0; iv<nvars; iv++) { \
strcpy(cmd,"nmod"); \ strcpy(cmd,vars[iv]); \
outfile << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \ outfile << cmd << " "<< myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \
strcpy(cmd,"angconv"); \ }; \
outfile << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \ }; \
strcpy(cmd,"globaloff"); \
outfile << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \
strcpy(cmd,"fineoff"); \
outfile << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \
strcpy(cmd,"angdir"); \
outfile << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \
strcpy(cmd,"ffdir"); \
outfile << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \
strcpy(cmd,"flatfield"); \
outfile << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \
strcpy(cmd,"badchannels"); \
outfile << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \
}; };
~angCalLogClass(){delete myDet; outfile.close();}; ~angCalLogClass(){delete myDet; outfile.close();};
#else
angCalLogClass() { createVars(); };
~angCalLogClass(){};
#endif
int addStep(double pos, string fname) {outfile << pos << " " << fname << endl; return 0;}; int addStep(double pos, string fname) {outfile << pos << " " << fname << endl; return 0;};
//
int readHeader(ifstream &infile, char *settings, int &maxmod, int &nmod, int &chanspermod, char *angconvfile, double &globaloff, double &fineoff, int &angdir, char *ffdir, char *fffile, char *badfile ) { \
nmod=0; chanspermod=0; globaloff=0; fineoff=0; angdir=1; \
strcpy(angconvfile,"none"); strcpy(ffdir,"none"); strcpy(fffile,"none"); strcpy(badfile,"none"); \
char line[1000], myvar[100], myarg[100]; \
int dum; \
float v; \
for (int iv=0; iv<nvars; iv++) { \
infile.getline(line,1000); \
sscanf(line,"%s %s", myvar, myarg); \
if (string(myvar)!=string(vars[iv]))
cout << "Found variable " << myvar << " instead of " << vars[iv] << endl;
else
switch (iv) { \
case 0: \
if (string(myarg).find("Mythen")!=string::npos) \
chanspermod=1280; \
else if (string(myarg).find("Gotthard")!=string::npos) \
chanspermod=1280; \
else \
chanspermod=65535; \
break; \
case 1: \
sscanf(myarg,"%d", &maxmod); \
break; \
case 2: \
sscanf(myarg,"%d", &nmod); \
break; \
case 3: \
strcpy(angconvfile,myarg); \
break; \
case 4: \
sscanf(myarg,"%f", &v); \
globaloff=v; \
break; \
case 5: \
sscanf(myarg,"%f", &v); \
fineoff=v; \
break; \
case 6: \
sscanf(myarg,"%d", &angdir); \
break; \
case 7: \
strcpy(ffdir,myarg); \
break; \
case 8: \
strcpy(fffile,myarg); \
break; \
case 9: \
strcpy(badfile,myarg); \
break; \
default: \
; \
}; \
if (infile.bad() || infile.eof()) { cout << "bad file "<< iv << endl; return -1;} \
} \
return 0; \
};
int getStep(ifstream &infile, double &threshold, char *datafname){ \
char line[1000]; \
float v;
infile.getline(line,1000); \
if (sscanf(line,"%g %s",&v, datafname)<2) return -1; \
threshold=v; \
if (infile.bad() || infile.eof()) \
return -1; \
return 0; \
};
private: private:
void createVars(){ \
strcpy(vars[0],"type"); \
strcpy(vars[1],"maxmod"); \
strcpy(vars[2],"nmod"); \
strcpy(vars[3],"angconv"); \
strcpy(vars[4],"globaloff"); \
strcpy(vars[5],"fineoffoff"); \
strcpy(vars[6],"angdir"); \
strcpy(vars[7],"ffdir"); \
strcpy(vars[8],"flatfield"); \
strcpy(vars[9],"badchannels"); \
nvars=10; \
};
#ifndef MYROOT
slsDetectorCommand *myDet; slsDetectorCommand *myDet;
#endif
ofstream outfile; ofstream outfile;
char vars[100][100];
int nvars;
}; };

View File

@ -0,0 +1,19 @@
#ifndef ANGLE_CONVERSION_CONSTANT_H
#define ANGLE_CONVERSION_CONSTANT_H
class angleConversionConstant {
public:
//typedef struct {
double center; /**< center of the module (channel at which the radius is perpendicular to the module surface) */
double ecenter; /**< error in the center determination */
double r_conversion; /**< detector pixel size (or strip pitch) divided by the diffractometer radius */
double er_conversion; /**< error in the r_conversion determination */
double offset; /**< the module offset i.e. the position of channel 0 with respect to the diffractometer 0 */
double eoffset; /**< error in the offset determination */
double tilt; /**< ossible tilt in the orthogonal direction (unused)*/
double etilt; /**< error in the tilt determination */
//} angleConversionConstant;
};
#endif

View File

@ -4,15 +4,16 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <math.h> #include <math.h>
#include "usersFunctions.h"
using namespace std; using namespace std;
angularConversion::angularConversion(): currentPosition(0), angularConversion::angularConversion(): angularConversionStatic(), currentPosition(0),
currentPositionIndex(0) currentPositionIndex(0)
{ {
//angleFunctionPointer=0; //angleFunctionPointer=0;
registerAngleFunctionCallback(&defaultAngleFunction); // registerAngleFunctionCallback(&defaultAngleFunction);
} }
@ -20,267 +21,33 @@ angularConversion::~angularConversion(){
} }
// int angularConversion::setAngularConversionPointer(angleConversionConstant *p, int *nm, int nch, int idet) {
// if (p) {
// angOff[idet]=p;
// nMods[idet]=nm;
// nCh[idet]=nch;
// } else {
// angOff[idet]=NULL;
// nMods[idet]=NULL;
// }
// return OK;
// }
double* angularConversion::convertAngles(double pos) { double* angularConversion::convertAngles(double pos) {
int imod=0;
double *ang=new double[getTotalNumberOfChannels()];
double enc=pos;
angleConversionConstant *p=NULL;
int ch0=0; int nmod=getNMods();
int chlast=getChansPerMod(0); int *chansPerMod=new int[nmod];
int nchmod=getChansPerMod(0); angleConversionConstant **angOff=new angleConversionConstant*[nmod];
p=getAngularConversionPointer(imod); int *mF=new int[nmod];
if (getMoveFlag(imod)==0) double fo=*fineOffset;
enc=0; double go=*globalOffset;
else int angdir=*angDirection;
enc=pos;
for (int ip=0; ip<getTotalNumberOfChannels(); ip++) {
#ifdef VERBOSE
// cout << "ip " << ip << " ch0 " << ch0 << " chlast " << chlast << " imod " << imod << endl;
#endif
if (ip>=chlast) {
imod++;
p=getAngularConversionPointer(imod);
if (getMoveFlag(imod)==0)
enc=0;
else
enc=pos;
ch0=chlast;
nchmod=getChansPerMod(imod);
if (nchmod>0)
chlast+=nchmod;
}
if (p) for (int im=0; im<nmod; im++) {
ang[ip]=angle(ip-ch0, \ angOff[im]=getAngularConversionPointer(im);
enc, \ mF[im]=getMoveFlag(im);
(*fineOffset)+(*globalOffset), \ chansPerMod[im]=getChansPerMod(im);
p->r_conversion, \
p->center, \
p->offset, \
p->tilt, \
*angDirection );
} }
return ang;
return angularConversionStatic::convertAngles(pos, getTotalNumberOfChannels(), chansPerMod, angOff,mF, fo, go, angdir);
} }
//static!
int angularConversion::readAngularConversion(string fname, int nmod, angleConversionConstant *angOff) {
ifstream infile;
string ss;
#ifdef VERBOSE
std::cout<< "Opening file "<< fname << std::endl;
#endif
infile.open(fname.c_str(), ios_base::in);
if (infile.is_open()) {
readAngularConversion(infile, nmod, angOff);
infile.close();
} else {
std::cout<< "Could not open calibration file "<< fname << std::endl;
return -1;
}
return 0;
}
//static
int angularConversion::readAngularConversion( ifstream& infile, int nmod, angleConversionConstant *angOff) {
string str;
int mod;
double center, ecenter;
double r_conv, er_conv;
double off, eoff;
string ss;
int interrupt=0;
int nm=0;
//" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n"
while (infile.good() and interrupt==0) {
getline(infile,str);
#ifdef VERBOSE
cout << "** mod " << nm << " " ;
std::cout<< str << std::endl;
#endif
istringstream ssstr(str);
ssstr >> ss >> mod;
ssstr >> ss >> center;
ssstr >> ss >> ecenter;
ssstr >> ss >> r_conv;
ssstr >> ss >> er_conv;
ssstr >> ss >> off;
ssstr >> ss >> eoff;
if (nm<nmod && nm>=0 ) {
angOff[nm].center=center;
angOff[nm].r_conversion=r_conv;
angOff[nm].offset=off;
angOff[nm].ecenter=ecenter;
angOff[nm].er_conversion=er_conv;
angOff[nm].eoffset=eoff;
} else
break;
//cout << nm<<" " << angOff[nm].offset << endl;
nm++;
if (nm>=nmod)
break;
}
return nm;
}
//static
int angularConversion:: writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff) {
ofstream outfile;
outfile.open (fname.c_str(),ios_base::out);
if (outfile.is_open())
{
writeAngularConversion(outfile, nmod, angOff);
outfile.close();
} else {
std::cout<< "Could not open file " << fname << "for writing"<< std::endl;
return -1;
}
//" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n"
return 0;
}
//static
int angularConversion:: writeAngularConversion(ofstream& outfile, int nmod, angleConversionConstant *angOff) {
for (int imod=0; imod<nmod; imod++) {
outfile << " module " << imod << " center "<< angOff[imod].center<<" +- "<< angOff[imod].ecenter<<" conversion "<< angOff[imod].r_conversion << " +- "<< angOff[imod].er_conversion << " offset "<< angOff[imod].offset << " +- "<< angOff[imod].eoffset << std::endl;
}
return 0;
}
//static
int angularConversion::resetMerging(double *mp, double *mv, double *me, int *mm, int nb) {
#ifdef VERBOSE
cout << "creating merging arrays "<< nb << endl;
#endif
for (int ibin=0; ibin<nb; ibin++) {
mp[ibin]=0;
mv[ibin]=0;
me[ibin]=0;
mm[ibin]=0;
}
return OK;
}
//static
int angularConversion::finalizeMerging(double *mp, double *mv, double *me, int *mm,int nb) {
int np=0;
for (int ibin=0; ibin<nb; ibin++) {
if (mm[ibin]>0) {
#ifdef VERBOSE
cout << "finalize " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl;
#endif
mp[np]=mp[ibin]/mm[ibin];
mv[np]=mv[ibin]/mm[ibin];
me[np]=me[ibin]/mm[ibin];
me[np]=sqrt(me[ibin]);
mm[np]=mm[ibin];
np++;
}
}
return np;
}
//static
int angularConversion::addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nbins, int *badChanMask ) {
double binmi=-180.;
int ibin=0;
if (p1==NULL)
return 0;
if (v1==NULL)
return FAIL;
if (mp==NULL) //can be changed if we want to use a fixed bin algorithm!
return FAIL;
if (mv==NULL)
return FAIL;
if (me==NULL)
return FAIL;
if (mm==NULL)
return FAIL;
if (nchans==0)
return FAIL;
if (binsize<=0)
return FAIL;
if (nbins<=0)
return FAIL;
for (int ip=0; ip<nchans; ip++) {
if (badChanMask) {
if (badChanMask[ip]) {
#ifdef VERBOSE
cout << "channel " << ip << " is bad " << endl;
#endif
continue;
}
}
ibin=(int)((p1[ip]-binmi)/binsize);
if (ibin<nbins && ibin>=0) {
mp[ibin]+=p1[ip];
mv[ibin]+=v1[ip];
if (e1)
me[ibin]+=(e1[ip]*e1[ip]);
else
me[ibin]+=v1[ip];
mm[ibin]++;
#ifdef VERBOSE
cout << "add " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl;
#endif
} else
return FAIL;
}
return OK;
}
int angularConversion::deleteMerging() { int angularConversion::deleteMerging() {
@ -317,7 +84,7 @@ int angularConversion::resetMerging() {
int angularConversion::resetMerging(double *mp, double *mv, double *me, int *mm) { int angularConversion::resetMerging(double *mp, double *mv, double *me, int *mm) {
getAngularConversionParameter(BIN_SIZE); getAngularConversionParameter(BIN_SIZE);
if (nBins) if (nBins)
return resetMerging(mp, mv, me, mm,nBins); return angularConversionStatic::resetMerging(mp, mv, me, mm,nBins);
else else
return FAIL; return FAIL;
} }
@ -340,7 +107,7 @@ int angularConversion::finalizeMerging() {
int angularConversion::finalizeMerging(double *mp, double *mv, double *me, int *mm) { int angularConversion::finalizeMerging(double *mp, double *mv, double *me, int *mm) {
if (nBins) if (nBins)
return finalizeMerging(mp, mv, me, mm, nBins); return angularConversionStatic::finalizeMerging(mp, mv, me, mm, nBins);
else else
return FAIL; return FAIL;
} }
@ -373,7 +140,7 @@ int angularConversion::addToMerging(double *p1, double *v1, double *e1, double
} }
int ret=addToMerging(p1, v1, e1, mp, mv,me, mm,getTotalNumberOfChannels(), *binSize,nBins, badChanMask ); int ret=angularConversionStatic::addToMerging(p1, v1, e1, mp, mv,me, mm,getTotalNumberOfChannels(), *binSize,nBins, badChanMask );
if (del) { if (del) {

View File

@ -2,12 +2,19 @@
#ifndef ANGULARCONVERSION_H #ifndef ANGULARCONVERSION_H
#define ANGULARCONVERSION_H #define ANGULARCONVERSION_H
#ifdef __CINT
#define MYROOT
#endif
#ifndef MYROOT
#include "slsDetectorBase.h" #include "slsDetectorBase.h"
#else
#include "sls_detector_defs.h"
#endif
#include <string> #include <string>
#include <fstream> #include <fstream>
#include "angularConversionStatic.h"
//double angle(int ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction) //double angle(int ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction)
@ -17,16 +24,6 @@ using namespace std;
/** /**
@short Angular conversion constants needed for a detector module @short Angular conversion constants needed for a detector module
*/ */
typedef struct {
double center; /**< center of the module (channel at which the radius is perpendicular to the module surface) */
double ecenter; /**< error in the center determination */
double r_conversion; /**< detector pixel size (or strip pitch) divided by the diffractometer radius */
double er_conversion; /**< error in the r_conversion determination */
double offset; /**< the module offset i.e. the position of channel 0 with respect to the diffractometer 0 */
double eoffset; /**< error in the offset determination */
double tilt; /**< ossible tilt in the orthogonal direction (unused)*/
double etilt; /**< error in the tilt determination */
} angleConversionConstant;
/** /**
@ -38,7 +35,9 @@ class containing the methods to set/unset the angular conversion and merge the d
The angular conversion itself is defined by the angle() function defined in usersFunctions.cpp The angular conversion itself is defined by the angle() function defined in usersFunctions.cpp
*/ */
class angularConversion : public virtual slsDetectorBase { class angularConversion : public virtual slsDetectorBase, public virtual angularConversionStatic
{
public: public:
/** default constructor */ /** default constructor */
@ -53,59 +52,11 @@ class angularConversion : public virtual slsDetectorBase {
/**
reads an angular conversion file
\param fname file to be read
\param nmod number of modules (maximum) to be read
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int readAngularConversion(string fname, int nmod, angleConversionConstant *angOff);
/**
reads an angular conversion file
\param ifstream input file stream to be read
\param nmod number of modules (maximum) to be read
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int readAngularConversion(ifstream& ifs, int nmod, angleConversionConstant *angOff);
/**
writes an angular conversion file
\param fname file to be written
\param nmod number of modules to be written
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff);
/**
writes an angular conversion file
\param ofstream output file stream
\param nmod number of modules to be written
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int writeAngularConversion(ofstream& ofs, int nmod, angleConversionConstant *angOff);
/** /**
pure virtual function pure virtual function
\param file name to be written (nmod and array of angular conversion constants default to the ones ot the slsDetector \param file name to be written (nmod and array of angular conversion constants default to the ones ot the slsDetector
*/ */
virtual int writeAngularConversion(string fname)=0; virtual int writeAngularConversion(string fname)=0;
/**
sets the arrays of the merged data to 0. NB The array should be created with size nbins >= 360./getBinSize();
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param nbins number of bins
\returns OK or FAIL
*/
static int resetMerging(double *mp, double *mv,double *me, int *mm, int nbins);
/** /**
sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize(); sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize();
\param mp already merged postions \param mp already merged postions
@ -121,23 +72,6 @@ class angularConversion : public virtual slsDetectorBase {
*/ */
int resetMerging(); int resetMerging();
/**
merge dataset
\param p1 angular positions of dataset
\param v1 data
\param e1 errors
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param nchans number of channels
\param binsize size of angular bin
\param nb number of angular bins
\param badChanMask badchannelmask (if NULL does not correct for bad channels)
\returns OK or FAIL
*/
static int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nb, int *badChanMask );
/** /**
merge dataset merge dataset
@ -164,17 +98,6 @@ class angularConversion : public virtual slsDetectorBase {
int addToMerging(double *p1, double *v1, double *e1,int *badChanMask); int addToMerging(double *p1, double *v1, double *e1,int *badChanMask);
/**
calculates the "final" positions, data value and errors for the merged data
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param nb number of bins
\returns FAIL or the number of non empty bins (i.e. points belonging to the pattern)
*/
static int finalizeMerging(double *mp, double *mv,double *me, int *mm, int nb);
/** /**
calculates the "final" positions, data value and errors for the merged data calculates the "final" positions, data value and errors for the merged data
\param mp already merged postions \param mp already merged postions
@ -368,6 +291,9 @@ class angularConversion : public virtual slsDetectorBase {
\returns array of angles corresponding to the channels \returns array of angles corresponding to the channels
*/ */
double* convertAngles(double pos); double* convertAngles(double pos);
/** /**
converts channel number to angle for the current encoder position converts channel number to angle for the current encoder position
\returns array of angles corresponding to the channels \returns array of angles corresponding to the channels
@ -377,6 +303,7 @@ class angularConversion : public virtual slsDetectorBase {
/** /**
\param imod module number \param imod module number
\returns move flag of the module (1 encoder is added to the angle, 0 not) \returns move flag of the module (1 encoder is added to the angle, 0 not)
Shold be module dependent!
*/ */
virtual int getMoveFlag(int imod)=0; virtual int getMoveFlag(int imod)=0;
@ -385,8 +312,11 @@ class angularConversion : public virtual slsDetectorBase {
*/ */
int getNumberOfPositions() {return *numberOfPositions;}; int getNumberOfPositions() {return *numberOfPositions;};
protected: protected:
/** pointer to number of positions for the acquisition*/ /** pointer to number of positions for the acquisition*/
int *numberOfPositions; int *numberOfPositions;
@ -439,11 +369,21 @@ class angularConversion : public virtual slsDetectorBase {
void registerAngleFunctionCallback(double( *fun)(double, double, double, double, double, double, double, int)) {angle = fun;};
private: private:
// int nChans;
// int nMods;
// int chansPerMod;
// int moveFlag;
/** merging bins */ /** merging bins */
double *mergingBins; double *mergingBins;
@ -456,8 +396,6 @@ class angularConversion : public virtual slsDetectorBase {
/** merging multiplicity */ /** merging multiplicity */
int *mergingMultiplicity; int *mergingMultiplicity;
double (*angle)(double, double, double, double, double, double, double, int);
}; };
#endif #endif

View File

@ -0,0 +1,268 @@
#include "angularConversionStatic.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <math.h>
#include "angleFunction.h"
using namespace std;
angularConversionStatic::angularConversionStatic()
{
//angleFunctionPointer=0;
registerAngleFunctionCallback(&defaultAngleFunction);
}
angularConversionStatic::~angularConversionStatic(){
}
double* angularConversionStatic::convertAngles(double pos, int nch, int *chansPerMod, angleConversionConstant **angOff, int *mF, double fo, double go, int angdir) {
int imod=0;
double *ang=new double[nch];
double enc=pos;
angleConversionConstant *p=NULL;
int ch0=0;
int chlast=chansPerMod[0];
int nchmod=chansPerMod[0];
p=angOff[imod];
if (mF[imod]==0)
enc=0;
else
enc=pos;
for (int ip=0; ip<nch; ip++) {
#ifdef VERBOSE
// cout << "ip " << ip << " ch0 " << ch0 << " chlast " << chlast << " imod " << imod << endl;
#endif
if (ip>=chlast) {
imod++;
p=angOff[imod];
if (mF[imod]==0)
enc=0;
else
enc=pos;
ch0=chlast;
nchmod=chansPerMod[imod];
if (nchmod>0)
chlast+=nchmod;
}
if (p)
ang[ip]=angle(ip-ch0, \
enc, \
fo+go, \
p->r_conversion, \
p->center, \
p->offset, \
p->tilt, \
angdir );
}
return ang;
}
//static!
int angularConversionStatic::readAngularConversion(string fname, int nmod, angleConversionConstant *angOff) {
ifstream infile;
string ss;
#ifdef VERBOSE
std::cout<< "Opening file "<< fname << std::endl;
#endif
infile.open(fname.c_str(), ios_base::in);
if (infile.is_open()) {
readAngularConversion(infile, nmod, angOff);
infile.close();
} else {
std::cout<< "Could not open calibration file "<< fname << std::endl;
return -1;
}
return 0;
}
//static
int angularConversionStatic::readAngularConversion( ifstream& infile, int nmod, angleConversionConstant *angOff) {
string str;
int mod;
double center, ecenter;
double r_conv, er_conv;
double off, eoff;
string ss;
int interrupt=0;
int nm=0;
//" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n"
while (infile.good() and interrupt==0) {
getline(infile,str);
#ifdef VERBOSE
cout << "** mod " << nm << " " ;
std::cout<< str << std::endl;
#endif
istringstream ssstr(str);
ssstr >> ss >> mod;
ssstr >> ss >> center;
ssstr >> ss >> ecenter;
ssstr >> ss >> r_conv;
ssstr >> ss >> er_conv;
ssstr >> ss >> off;
ssstr >> ss >> eoff;
if (nm<nmod && nm>=0 ) {
angOff[nm].center=center;
angOff[nm].r_conversion=r_conv;
angOff[nm].offset=off;
angOff[nm].ecenter=ecenter;
angOff[nm].er_conversion=er_conv;
angOff[nm].eoffset=eoff;
} else
break;
//cout << nm<<" " << angOff[nm].offset << endl;
nm++;
if (nm>=nmod)
break;
}
return nm;
}
//static
int angularConversionStatic:: writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff) {
ofstream outfile;
outfile.open (fname.c_str(),ios_base::out);
if (outfile.is_open())
{
writeAngularConversion(outfile, nmod, angOff);
outfile.close();
} else {
std::cout<< "Could not open file " << fname << "for writing"<< std::endl;
return -1;
}
//" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n"
return 0;
}
//static
int angularConversionStatic:: writeAngularConversion(ofstream& outfile, int nmod, angleConversionConstant *angOff) {
for (int imod=0; imod<nmod; imod++) {
outfile << " module " << imod << " center "<< angOff[imod].center<<" +- "<< angOff[imod].ecenter<<" conversion "<< angOff[imod].r_conversion << " +- "<< angOff[imod].er_conversion << " offset "<< angOff[imod].offset << " +- "<< angOff[imod].eoffset << std::endl;
}
return 0;
}
//static
int angularConversionStatic::resetMerging(double *mp, double *mv, double *me, int *mm, int nb) {
#ifdef VERBOSE
cout << "creating merging arrays "<< nb << endl;
#endif
for (int ibin=0; ibin<nb; ibin++) {
mp[ibin]=0;
mv[ibin]=0;
me[ibin]=0;
mm[ibin]=0;
}
return OK;
}
//static
int angularConversionStatic::finalizeMerging(double *mp, double *mv, double *me, int *mm,int nb) {
int np=0;
for (int ibin=0; ibin<nb; ibin++) {
if (mm[ibin]>0) {
#ifdef VERBOSE
cout << "finalize " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl;
#endif
mp[np]=mp[ibin]/mm[ibin];
mv[np]=mv[ibin]/mm[ibin];
me[np]=me[ibin]/mm[ibin];
me[np]=sqrt(me[ibin]);
mm[np]=mm[ibin];
np++;
}
}
return np;
}
//static
int angularConversionStatic::addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nbins, int *badChanMask ) {
double binmi=-180.;
int ibin=0;
if (p1==NULL)
return 0;
if (v1==NULL)
return FAIL;
if (mp==NULL) //can be changed if we want to use a fixed bin algorithm!
return FAIL;
if (mv==NULL)
return FAIL;
if (me==NULL)
return FAIL;
if (mm==NULL)
return FAIL;
if (nchans==0)
return FAIL;
if (binsize<=0)
return FAIL;
if (nbins<=0)
return FAIL;
for (int ip=0; ip<nchans; ip++) {
if (badChanMask) {
if (badChanMask[ip]) {
#ifdef VERBOSE
cout << "channel " << ip << " is bad " << endl;
#endif
continue;
}
}
ibin=(int)((p1[ip]-binmi)/binsize);
if (ibin<nbins && ibin>=0) {
mp[ibin]+=p1[ip];
mv[ibin]+=v1[ip];
if (e1)
me[ibin]+=(e1[ip]*e1[ip]);
else
me[ibin]+=v1[ip];
mm[ibin]++;
#ifdef VERBOSE
cout << "add " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl;
#endif
} else
return FAIL;
}
return OK;
}

View File

@ -0,0 +1,526 @@
#include "angularConversion.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <math.h>
#ifndef MYROOT
#include "usersFunctions.h"
#endif
#include "angleFunction.h"
using namespace std;
angularConversion::angularConversion(): currentPosition(0),
currentPositionIndex(0)
{
//angleFunctionPointer=0;
registerAngleFunctionCallback(&defaultAngleFunction);
}
angularConversion::~angularConversion(){
}
// int angularConversion::setAngularConversionPointer(angleConversionConstant *p, int *nm, int nch, int idet) {
// if (p) {
// angOff[idet]=p;
// nMods[idet]=nm;
// nCh[idet]=nch;
// } else {
// angOff[idet]=NULL;
// nMods[idet]=NULL;
// }
// return OK;
// }
double* angularConversion::convertAngles(double pos, int nch) {
int imod=0;
double *ang=new double[nch];
double enc=pos;
angleConversionConstant *p=NULL;
int ch0=0;
int chlast=getChansPerMod(0);
int nchmod=getChansPerMod(0);
p=getAngularConversionPointer(imod);
if (getMoveFlag(imod)==0)
enc=0;
else
enc=pos;
for (int ip=0; ip<nch; ip++) {
#ifdef VERBOSE
// cout << "ip " << ip << " ch0 " << ch0 << " chlast " << chlast << " imod " << imod << endl;
#endif
if (ip>=chlast) {
imod++;
p=getAngularConversionPointer(imod);
if (getMoveFlag(imod)==0)
enc=0;
else
enc=pos;
ch0=chlast;
nchmod=getChansPerMod(imod);
if (nchmod>0)
chlast+=nchmod;
}
if (p)
ang[ip]=angle(ip-ch0, \
enc, \
(*fineOffset)+(*globalOffset), \
p->r_conversion, \
p->center, \
p->offset, \
p->tilt, \
*angDirection );
}
return ang;
}
//static!
int angularConversion::readAngularConversion(string fname, int nmod, angleConversionConstant *angOff) {
ifstream infile;
string ss;
#ifdef VERBOSE
std::cout<< "Opening file "<< fname << std::endl;
#endif
infile.open(fname.c_str(), ios_base::in);
if (infile.is_open()) {
readAngularConversion(infile, nmod, angOff);
infile.close();
} else {
std::cout<< "Could not open calibration file "<< fname << std::endl;
return -1;
}
return 0;
}
//static
int angularConversion::readAngularConversion( ifstream& infile, int nmod, angleConversionConstant *angOff) {
string str;
int mod;
double center, ecenter;
double r_conv, er_conv;
double off, eoff;
string ss;
int interrupt=0;
int nm=0;
//" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n"
while (infile.good() and interrupt==0) {
getline(infile,str);
#ifdef VERBOSE
cout << "** mod " << nm << " " ;
std::cout<< str << std::endl;
#endif
istringstream ssstr(str);
ssstr >> ss >> mod;
ssstr >> ss >> center;
ssstr >> ss >> ecenter;
ssstr >> ss >> r_conv;
ssstr >> ss >> er_conv;
ssstr >> ss >> off;
ssstr >> ss >> eoff;
if (nm<nmod && nm>=0 ) {
angOff[nm].center=center;
angOff[nm].r_conversion=r_conv;
angOff[nm].offset=off;
angOff[nm].ecenter=ecenter;
angOff[nm].er_conversion=er_conv;
angOff[nm].eoffset=eoff;
} else
break;
//cout << nm<<" " << angOff[nm].offset << endl;
nm++;
if (nm>=nmod)
break;
}
return nm;
}
//static
int angularConversion:: writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff) {
ofstream outfile;
outfile.open (fname.c_str(),ios_base::out);
if (outfile.is_open())
{
writeAngularConversion(outfile, nmod, angOff);
outfile.close();
} else {
std::cout<< "Could not open file " << fname << "for writing"<< std::endl;
return -1;
}
//" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n"
return 0;
}
//static
int angularConversion:: writeAngularConversion(ofstream& outfile, int nmod, angleConversionConstant *angOff) {
for (int imod=0; imod<nmod; imod++) {
outfile << " module " << imod << " center "<< angOff[imod].center<<" +- "<< angOff[imod].ecenter<<" conversion "<< angOff[imod].r_conversion << " +- "<< angOff[imod].er_conversion << " offset "<< angOff[imod].offset << " +- "<< angOff[imod].eoffset << std::endl;
}
return 0;
}
//static
int angularConversion::resetMerging(double *mp, double *mv, double *me, int *mm, int nb) {
#ifdef VERBOSE
cout << "creating merging arrays "<< nb << endl;
#endif
for (int ibin=0; ibin<nb; ibin++) {
mp[ibin]=0;
mv[ibin]=0;
me[ibin]=0;
mm[ibin]=0;
}
return OK;
}
//static
int angularConversion::finalizeMerging(double *mp, double *mv, double *me, int *mm,int nb) {
int np=0;
for (int ibin=0; ibin<nb; ibin++) {
if (mm[ibin]>0) {
#ifdef VERBOSE
cout << "finalize " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl;
#endif
mp[np]=mp[ibin]/mm[ibin];
mv[np]=mv[ibin]/mm[ibin];
me[np]=me[ibin]/mm[ibin];
me[np]=sqrt(me[ibin]);
mm[np]=mm[ibin];
np++;
}
}
return np;
}
//static
int angularConversion::addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nbins, int *badChanMask ) {
double binmi=-180.;
int ibin=0;
if (p1==NULL)
return 0;
if (v1==NULL)
return FAIL;
if (mp==NULL) //can be changed if we want to use a fixed bin algorithm!
return FAIL;
if (mv==NULL)
return FAIL;
if (me==NULL)
return FAIL;
if (mm==NULL)
return FAIL;
if (nchans==0)
return FAIL;
if (binsize<=0)
return FAIL;
if (nbins<=0)
return FAIL;
for (int ip=0; ip<nchans; ip++) {
if (badChanMask) {
if (badChanMask[ip]) {
#ifdef VERBOSE
cout << "channel " << ip << " is bad " << endl;
#endif
continue;
}
}
ibin=(int)((p1[ip]-binmi)/binsize);
if (ibin<nbins && ibin>=0) {
mp[ibin]+=p1[ip];
mv[ibin]+=v1[ip];
if (e1)
me[ibin]+=(e1[ip]*e1[ip]);
else
me[ibin]+=v1[ip];
mm[ibin]++;
#ifdef VERBOSE
cout << "add " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl;
#endif
} else
return FAIL;
}
return OK;
}
int angularConversion::deleteMerging() {
if (mergingBins)
delete [] mergingBins;
if (mergingCounts)
delete [] mergingCounts;
if (mergingErrors)
delete [] mergingErrors;
}
int angularConversion::resetMerging() {
getAngularConversionParameter(BIN_SIZE);
mergingBins=new double[nBins];
mergingCounts=new double[nBins];
mergingErrors=new double[nBins];
mergingMultiplicity=new int[nBins];
return resetMerging(mergingBins, mergingCounts, mergingErrors, mergingMultiplicity);
}
int angularConversion::resetMerging(double *mp, double *mv, double *me, int *mm) {
getAngularConversionParameter(BIN_SIZE);
if (nBins)
return resetMerging(mp, mv, me, mm,nBins);
else
return FAIL;
}
int angularConversion::finalizeMerging() {
int np=finalizeMerging(mergingBins, mergingCounts, mergingErrors, mergingMultiplicity);
if (mergingMultiplicity)
delete [] mergingMultiplicity;
return np;
}
int angularConversion::finalizeMerging(double *mp, double *mv, double *me, int *mm) {
if (nBins)
return finalizeMerging(mp, mv, me, mm, nBins);
else
return FAIL;
}
int angularConversion::addToMerging(double *p1, double *v1, double *e1, int *badChanMask ) {
return addToMerging(p1,v1,e1,mergingBins,mergingCounts, mergingErrors, mergingMultiplicity, badChanMask);
}
int angularConversion::addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int *badChanMask ) {
int del=0;
if (getAngularConversionParameter(BIN_SIZE)==0){
cout << "no bin size " << endl;
return FAIL;
}
if (nBins==0) {
cout << "no bins " << endl;
return FAIL;
}
if (p1==NULL) {
del=1;
p1=convertAngles();
}
int ret=addToMerging(p1, v1, e1, mp, mv,me, mm,getTotalNumberOfChannels(), *binSize,nBins, badChanMask );
if (del) {
delete [] p1;
p1=NULL;
}
return ret;
}
/**
sets the value of s angular conversion parameter
\param c can be ANGULAR_DIRECTION, GLOBAL_OFFSET, FINE_OFFSET, BIN_SIZE
\param v the value to be set
\returns the actual value
*/
double angularConversion::setAngularConversionParameter(angleConversionParameter c, double v){
switch (c) {
case ANGULAR_DIRECTION:
if (v<0)
*angDirection=-1;
else
*angDirection=1;
return *angDirection;
case GLOBAL_OFFSET:
*globalOffset=v;
return *globalOffset;
case FINE_OFFSET:
*fineOffset=v;
return *fineOffset;
case BIN_SIZE:
if (v>0) {
*binSize=v;
nBins=360./(*binSize);
}
return *binSize;
case MOVE_FLAG:
if (moveFlag) {
if (v>0)
*moveFlag=1;
else if (v==0)
*moveFlag=0;
return *moveFlag;
}
return -1;
default:
return 0;
}
}
/**
returns the value of an angular conversion parameter
\param c can be ANGULAR_DIRECTION, GLOBAL_OFFSET, FINE_OFFSET, BIN_SIZE
\returns the actual value
*/
double angularConversion::getAngularConversionParameter(angleConversionParameter c) {
switch (c) {
case ANGULAR_DIRECTION:
return *angDirection;
case GLOBAL_OFFSET:
return *globalOffset;
case FINE_OFFSET:
return *fineOffset;
case BIN_SIZE:
if (*binSize>0)
nBins=360./(*binSize);
else
nBins=0;
return *binSize;
case MOVE_FLAG:
if (moveFlag)
return *moveFlag;
else
return -1;
default:
return 0;
}
}
int angularConversion::setAngularConversionFile(string fname) {
if (fname=="") {
setAngularCorrectionMask(0);
#ifdef VERBOSE
std::cout << "Unsetting angular conversion" << std::endl;
#endif
} else {
if (fname=="default") {
fname=string(angConvFile);
}
#ifdef VERBOSE
std::cout << "Setting angular conversion to " << fname << std:: endl;
#endif
if (readAngularConversionFile(fname)>=0) {
setAngularCorrectionMask(1);
strcpy(angConvFile,fname.c_str());
}
}
return setAngularCorrectionMask();
}
/*
set positions for the acquisition
\param nPos number of positions
\param pos array with the encoder positions
\returns number of positions
*/
int angularConversion::setPositions(int nPos, double *pos){
if (nPos>=0)
*numberOfPositions=nPos;
for (int ip=0; ip<nPos; ip++)
detPositions[ip]=pos[ip];
return *numberOfPositions;
}
/*
get positions for the acquisition
\param pos array which will contain the encoder positions
\returns number of positions
*/
int angularConversion::getPositions(double *pos){
if (pos) {
for (int ip=0; ip<(*numberOfPositions); ip++)
pos[ip]=detPositions[ip];
}
return *numberOfPositions;
}

View File

@ -0,0 +1,158 @@
#ifndef ANGULARCONVERSIONSTATIC_H
#define ANGULARCONVERSIONSTATIC_H
#ifdef __CINT
#define MYROOT
#endif
#include "sls_detector_defs.h"
#include <string>
#include <fstream>
#include "angleConversionConstant.h"
//double angle(int ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction)
using namespace std;
/**
@short Angular conversion constants needed for a detector module
*/
/**
@short methods to set/unset the angular conversion and merge the data
class containing the methods to set/unset the angular conversion and merge the data
The angular conversion itself is defined by the angle() function defined in usersFunctions.cpp
*/
class angularConversionStatic : public virtual slsDetectorDefs
{
public:
/** default constructor */
angularConversionStatic();
/** virtual destructor */
virtual ~angularConversionStatic();
//virtual int readAngularConversion(string fname)=0;
/**
reads an angular conversion file
\param fname file to be read
\param nmod number of modules (maximum) to be read
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int readAngularConversion(string fname, int nmod, angleConversionConstant *angOff);
/**
reads an angular conversion file
\param ifstream input file stream to be read
\param nmod number of modules (maximum) to be read
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int readAngularConversion(ifstream& ifs, int nmod, angleConversionConstant *angOff);
/**
writes an angular conversion file
\param fname file to be written
\param nmod number of modules to be written
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff);
/**
writes an angular conversion file
\param ofstream output file stream
\param nmod number of modules to be written
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int writeAngularConversion(ofstream& ofs, int nmod, angleConversionConstant *angOff);
/**
sets the arrays of the merged data to 0. NB The array should be created with size nbins >= 360./getBinSize();
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param nbins number of bins
\returns OK or FAIL
*/
static int resetMerging(double *mp, double *mv,double *me, int *mm, int nbins);
/**
merge dataset
\param p1 angular positions of dataset
\param v1 data
\param e1 errors
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param nchans number of channels
\param binsize size of angular bin
\param nb number of angular bins
\param badChanMask badchannelmask (if NULL does not correct for bad channels)
\returns OK or FAIL
*/
static int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nb, int *badChanMask );
/**
calculates the "final" positions, data value and errors for the merged data
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param nb number of bins
\returns FAIL or the number of non empty bins (i.e. points belonging to the pattern)
*/
static int finalizeMerging(double *mp, double *mv,double *me, int *mm, int nb);
/**
converts channel number to angle
\param pos encoder position
\returns array of angles corresponding to the channels
*/
double* convertAngles(double pos, int nch, int *chansPerMod, angleConversionConstant **angOff, int *mF, double fo, double go, int angdir);
protected:
int registerAngleFunctionCallback(double (*fun)(double, double, double, double, double, double, double, int)) {angle = fun; return 0;};
private:
double (*angle)(double, double, double, double, double, double, double, int);
};
#endif

View File

@ -0,0 +1,486 @@
#ifndef ANGULARCONVERSIONSTATIC_H
#define ANGULARCONVERSIONSTATIC_H
#ifdef __CINT
#define MYROOT
#endif
#include "sls_detector_defs.h"
#include <string>
#include <fstream>
#include "angleConversionConstant.h"
//double angle(int ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction)
using namespace std;
/**
@short Angular conversion constants needed for a detector module
*/
/**
@short methods to set/unset the angular conversion and merge the data
class containing the methods to set/unset the angular conversion and merge the data
The angular conversion itself is defined by the angle() function defined in usersFunctions.cpp
*/
class angularConversion
#ifndef MYROOT
: public virtual slsDetectorBase
#else
: public virtual slsDetectorDefs
#endif
{
public:
/** default constructor */
angularConversion();
/** virtual destructor */
virtual ~angularConversion();
//virtual int readAngularConversion(string fname)=0;
/**
reads an angular conversion file
\param fname file to be read
\param nmod number of modules (maximum) to be read
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int readAngularConversion(string fname, int nmod, angleConversionConstant *angOff);
/**
reads an angular conversion file
\param ifstream input file stream to be read
\param nmod number of modules (maximum) to be read
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int readAngularConversion(ifstream& ifs, int nmod, angleConversionConstant *angOff);
/**
writes an angular conversion file
\param fname file to be written
\param nmod number of modules to be written
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff);
/**
writes an angular conversion file
\param ofstream output file stream
\param nmod number of modules to be written
\param angOff pointer to array of angleConversionConstants
\returns OK or FAIL
*/
static int writeAngularConversion(ofstream& ofs, int nmod, angleConversionConstant *angOff);
/**
pure virtual function
\param file name to be written (nmod and array of angular conversion constants default to the ones ot the slsDetector
*/
virtual int writeAngularConversion(string fname)=0;
/**
sets the arrays of the merged data to 0. NB The array should be created with size nbins >= 360./getBinSize();
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param nbins number of bins
\returns OK or FAIL
*/
static int resetMerging(double *mp, double *mv,double *me, int *mm, int nbins);
/**
sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize();
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\returns OK or FAIL
*/
int resetMerging(double *mp, double *mv,double *me, int *mm);
/**
creates the arrays for merging the data and sets them to 0.
*/
int resetMerging();
/**
merge dataset
\param p1 angular positions of dataset
\param v1 data
\param e1 errors
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param nchans number of channels
\param binsize size of angular bin
\param nb number of angular bins
\param badChanMask badchannelmask (if NULL does not correct for bad channels)
\returns OK or FAIL
*/
static int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nb, int *badChanMask );
/**
merge dataset
\param p1 angular positions of dataset
\param v1 data
\param e1 errors
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param badChanMask badchannelmask (if NULL does not correct for bad channels)
\returns OK or FAIL
*/
int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int *badChanMask);
/**
merge dataset
\param p1 angular positions of dataset
\param v1 data
\param e1 errors
\param badChanMask badchannelmask (if NULL does not correct for bad channels)
\returns OK or FAIL
*/
int addToMerging(double *p1, double *v1, double *e1,int *badChanMask);
/**
calculates the "final" positions, data value and errors for the merged data
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\param nb number of bins
\returns FAIL or the number of non empty bins (i.e. points belonging to the pattern)
*/
static int finalizeMerging(double *mp, double *mv,double *me, int *mm, int nb);
/**
calculates the "final" positions, data value and errors for the merged data
\param mp already merged postions
\param mv already merged data
\param me already merged errors (squared sum)
\param mm multiplicity of merged arrays
\returns FAIL or the number of non empty bins (i.e. points belonging to the pattern)
*/
int finalizeMerging(double *mp, double *mv,double *me, int *mm);
/**
calculates the "final" positions, data value and errors for the merged data
\returns FAIL or the number of non empty bins (i.e. points belonging to the pattern)
*/
int finalizeMerging();
/**
set detector global offset
\param f global offset to be set
\returns actual global offset
*/
double setGlobalOffset(double f){return setAngularConversionParameter(GLOBAL_OFFSET,f);};
/**
set detector fine offset
\param f global fine to be set
\returns actual fine offset
*/
double setFineOffset(double f){return setAngularConversionParameter(FINE_OFFSET,f);};
/**
get detector fine offset
\returns actual fine offset
*/
double getFineOffset(){return getAngularConversionParameter(FINE_OFFSET);};
/**
get detector global offset
\returns actual global offset
*/
double getGlobalOffset(){return getAngularConversionParameter(GLOBAL_OFFSET);};
/**
set detector bin size
\param bs bin size to be set
\returns actual bin size
*/
double setBinSize(double bs){if (bs>0) nBins=360/bs; return setAngularConversionParameter(BIN_SIZE,bs);};
/**
get detector bin size
\returns detector bin size used for merging (approx angular resolution)
*/
double getBinSize() {return getAngularConversionParameter(BIN_SIZE);};
/**
get angular direction
\returns actual angular direction (1 is channel number increasing with angle, -1 decreasing)
*/
int getAngularDirection(){return (int)getAngularConversionParameter(ANGULAR_DIRECTION);};
/**
set angular direction
\param d angular direction to be set (1 is channel number increasing with angle, -1 decreasing)
\returns actual angular direction (1 is channel number increasing with angle, -1 decreasing)
*/
int setAngularDirection(int d){return (int)setAngularConversionParameter(ANGULAR_DIRECTION, (double)d);};
/**
\returns number of angular bins in the merging (360./binsize)
*/
int getNumberOfAngularBins(){return nBins;};
/**
get angular conversion
\param direction reference to diffractometer direction
\param angconv array that will be filled with the angular conversion constants
\returns 0 if angular conversion disabled, >0 otherwise
*/
virtual int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL)=0;
/**
set angular conversion parameter
\param c parameter type (globaloffset, fineoffset, binsize, angular direction, move flag)
\param v value to be set
\returns actual value
*/
double setAngularConversionParameter(angleConversionParameter c, double v);
/**
get angular conversion parameter
\param c parameter type (globaloffset, fineoffset, binsize, angular direction, move flag)
\returns actual value
*/
double getAngularConversionParameter(angleConversionParameter c);
/**
set positions for the acquisition
\param nPos number of positions
\param pos array with the encoder positions
\returns number of positions
*/
virtual int setPositions(int nPos, double *pos);
/**
get positions for the acquisition
\param pos array which will contain the encoder positions
\returns number of positions
*/
virtual int getPositions(double *pos=NULL);
/**
deletes the array of merged data
\returns OK
*/
int deleteMerging();
/**
\returns pointer to the array o merged positions
*/
double *getMergedPositions(){return mergingBins;};
/**
\returns pointer to the array of merged counts
*/
double *getMergedCounts(){return mergingCounts;};
/**
\returns pointer to the array of merged errors
*/
double *getMergedErrors(){return mergingErrors;};
/**
sets the angular conversion file
\param fname file to read
\returns angular conversion flag
*/
int setAngularConversionFile(string fname);
/**
returns the angular conversion file
*/
string getAngularConversionFile(){if (setAngularCorrectionMask()) return string(angConvFile); else return string("none");};
/**
reads teh angular conversion file for the (multi)detector and writes it to shared memory
*/
virtual int readAngularConversionFile(string fname="")=0;
/**
\returns number of modules of the (multi)detector
*/
virtual int getNMods()=0;
/**
returns number of channels in the module
\param imod module number
\returns number of channels in the module
*/
virtual int getChansPerMod(int imod=0)=0;
/**
get the angular conversion contant of one modules
\param imod module number
\returns pointer to the angular conversion constant
*/
virtual angleConversionConstant *getAngularConversionPointer(int imod=0)=0;
/**
converts channel number to angle
\param pos encoder position
\returns array of angles corresponding to the channels
*/
double* convertAngles(double pos){return convertAngles(pos, getTotalNumberOfChannels());}
double* convertAngles(double pos, int nch);
/**
converts channel number to angle for the current encoder position
\returns array of angles corresponding to the channels
*/
double *convertAngles(){return convertAngles(currentPosition);};
/**
\param imod module number
\returns move flag of the module (1 encoder is added to the angle, 0 not)
Shold be module dependent!
*/
virtual int getMoveFlag(int imod)=0;
/**
returns number of positions
*/
int getNumberOfPositions() {return *numberOfPositions;};
protected:
/** pointer to number of positions for the acquisition*/
int *numberOfPositions;
/** pointer to the detector positions for the acquisition*/
double *detPositions;
/** pointer to angular conversion file name*/
char *angConvFile;
/** pointer to angular bin size*/
double *binSize;
/** pointer to beamlien fine offset*/
double *fineOffset;
/** pointer to beamlien global offset*/
double *globalOffset;
/** pointer to beamlien angular direction*/
int *angDirection;
/** pointer to detector move flag (1 moves with encoder, 0 not)*/
int *moveFlag;
/** number of bins for angular conversion (360./binsize)*/
int nBins;
/**
current position of the detector
*/
double currentPosition;
/**
current position index of the detector
*/
int currentPositionIndex;
/**
enables/disable the angular conversion
\param i 1 sets, 0 unsets,, -1 gets
\returns actual angular conversion flag
*/
virtual int setAngularCorrectionMask(int i=-1)=0;
/**
returns current position index
*/
int getCurrentPositionIndex() {return currentPositionIndex;};
void incrementPositionIndex() {currentPositionIndex++;};
void registerAngleFunctionCallback(double( *fun)(double, double, double, double, double, double, double, int)) {angle = fun;};
private:
// int nChans;
// int nMods;
// int chansPerMod;
// int moveFlag;
/** merging bins */
double *mergingBins;
/** merging counts */
double *mergingCounts;
/** merging errors */
double *mergingErrors;
/** merging multiplicity */
int *mergingMultiplicity;
double (*angle)(double, double, double, double, double, double, double, int);
};
#endif

View File

@ -123,7 +123,6 @@ class enCalLogClass {
slsDetectorCommand *myDet; slsDetectorCommand *myDet;
#endif #endif
ofstream outfile; ofstream outfile;
ifstream infile;
char vars[4][100]; char vars[4][100];
}; };

View File

@ -9,8 +9,12 @@
#include <sstream> #include <sstream>
#include <queue> #include <queue>
#include <math.h> #include <math.h>
#include "sls_detector_defs.h"
#ifdef __CINT
#define MYROOT
#endif
#include "sls_detector_defs.h"
using namespace std; using namespace std;
/** /**
@short class handling the data file I/O flags @short class handling the data file I/O flags

View File

@ -1,12 +1,15 @@
#ifndef DEFAULT_ANGLE_FUNCTION_H
#define DEFAULT_ANGLE_FUNCTION_H
/* /*
contains the conversion channel-angle for a module channel contains the conversion channel-angle for a module channel
conv_r=pitch/radius conv_r=pitch/radius
*/ */
#define PI 3.14159265358979323846
#include <math.h>
double defaultAngleFunction(double ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction) {\ double defaultAngleFunction(double ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction) {\
(void) tilt; \ (void) tilt; \
return 180./PI*(center*conv_r+direction*atan((double)(ichan-center)*conv_r))+encoder+totalOffset+offset;\ return 180./PI*(center*conv_r+direction*atan((double)(ichan-center)*conv_r))+encoder+totalOffset+offset; };
};
#endif

View File

@ -6,7 +6,7 @@ Functions depending on the experimental setup should be defined here
******************************************************************/ ******************************************************************/
#define PI 3.14159265358979323846 //#define PI 3.14159265358979323846
#ifdef EPICS #ifdef EPICS
@ -14,7 +14,6 @@ Functions depending on the experimental setup should be defined here
#include <epicsEvent.h> #include <epicsEvent.h>
#endif #endif
#include "detectorData.h" #include "detectorData.h"
#include "angleFunction.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -30,7 +29,7 @@ extern "C" {
#endif #endif
double defaultAngleFunction(double ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction); // double defaultAngleFunction(double ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction);
double defaultGetPosition(void *d); double defaultGetPosition(void *d);
int defaultGoToPosition(double p,void *d); int defaultGoToPosition(double p,void *d);
int defaultGoToPositionNoWait(double p,void *d); int defaultGoToPositionNoWait(double p,void *d);