Detectors types can (should) be configured in the multiSlsDetector structure

git-svn-id: file:///afs/psi.ch/project/sls_det_software/svn/slsDetectorSoftware@181 951219d9-93cf-4727-9268-0efd64621fa3
This commit is contained in:
bergamaschi
2012-05-22 12:24:15 +00:00
parent 83ee449e3c
commit 0bab16cde7
13 changed files with 650 additions and 248 deletions

View File

@ -10,7 +10,7 @@ SRC_CLNT= slsDetectorAnalysis/fileIO.cpp MySocketTCP/MySocketTCP.cpp usersFuncti
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 HEADERS = $(SRC_CLNT:.cpp=.h) commonFiles/sls_detector_defs.h slsDetectorAnalysis/detectorData.h slsDetector/slsDetectorBase.h slsDetector/slsDetectorUsers.h multiSlsDetector/multiSlsDetectorCommand.h

View File

@ -12,7 +12,8 @@ ID: $Id$
#include "multiSlsDetector.h" #include "multiSlsDetector.h"
#include "slsDetector.h" #include "slsDetector.h"
#include "slsDetectorCommand.h" #include "multiSlsDetectorCommand.h"
#include "multiSlsDetectorClient.h"
#include "usersFunctions.h" #include "usersFunctions.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/ipc.h> #include <sys/ipc.h>
@ -26,6 +27,12 @@ using namespace std;
int multiSlsDetector::freeSharedMemory() { int multiSlsDetector::freeSharedMemory() {
// Detach Memory address // Detach Memory address
for (int id=0; id<thisMultiDetector->numberOfDetectors; id++) {
if (detectors[id])
detectors[id]->freeSharedMemory();
}
if (shmdt(thisMultiDetector) == -1) { if (shmdt(thisMultiDetector) == -1) {
perror("shmdt failed\n"); perror("shmdt failed\n");
return FAIL; return FAIL;
@ -343,7 +350,7 @@ int multiSlsDetector::addSlsDetector(int id, int pos) {
} }
string multiSlsDetector::setHostname(char* name, int pos){ string multiSlsDetector::setHostname(const char* name, int pos){
// int id=0; // int id=0;
string s; string s;
@ -361,7 +368,6 @@ string multiSlsDetector::setHostname(char* name, int pos){
addSlsDetector(hn, pos); addSlsDetector(hn, pos);
} else { } else {
while (p2!=string::npos) { while (p2!=string::npos) {
strcpy(hn,s.substr(p1,p2-p1).c_str()); strcpy(hn,s.substr(p1,p2-p1).c_str());
addSlsDetector(hn, pos); addSlsDetector(hn, pos);
s=s.substr(p2+1); s=s.substr(p2+1);
@ -372,6 +378,36 @@ string multiSlsDetector::setHostname(char* name, int pos){
return getHostname(pos); return getHostname(pos);
} }
string multiSlsDetector::ssetDetectorsType(string name, int pos) {
// int id=0;
string s;
if (pos>=0) {
if (getDetectorType(name)!=GET_DETECTOR_TYPE)
addSlsDetector(name.c_str(), pos);
} else {
removeSlsDetector(); //reset detector list!
size_t p1=0;
s=string(name);
size_t p2=s.find('+',p1);
char hn[1000];
if (p2==string::npos) {
strcpy(hn,s.c_str());
addSlsDetector(hn, pos);
} else {
while (p2!=string::npos) {
strcpy(hn,s.substr(p1,p2-p1).c_str());
if (getDetectorType(hn)!=GET_DETECTOR_TYPE)
addSlsDetector(hn, pos);
s=s.substr(p2+1);
p2=s.find('+');
}
}
}
return sgetDetectorsType(pos);
}
string multiSlsDetector::getHostname(int pos) { string multiSlsDetector::getHostname(int pos) {
@ -416,6 +452,36 @@ slsDetectorDefs::detectorType multiSlsDetector::getDetectorsType(int pos) {
} }
string multiSlsDetector::sgetDetectorsType(int pos) {
string s=string("");
#ifdef VERBOSE
cout << "returning type" << pos << endl;
#endif
if (pos>=0) {
if (detectors[pos])
return detectors[pos]->sgetDetectorsType();
} else {
for (int ip=0; ip<thisMultiDetector->numberOfDetectors; ip++) {
#ifdef VERBOSE
cout << "detector " << ip << endl;
#endif
if (detectors[ip]) {
s+=detectors[ip]->sgetDetectorsType();
s+=string("+");
}
#ifdef VERBOSE
cout << "type " << s << endl;
#endif
}
}
return s;
}
int multiSlsDetector::getDetectorId(int pos) { int multiSlsDetector::getDetectorId(int pos) {
#ifdef VERBOSE #ifdef VERBOSE
@ -445,10 +511,11 @@ int multiSlsDetector::setDetectorId(int ival, int pos){
} }
int multiSlsDetector::addSlsDetector(char *name, int pos) { int multiSlsDetector::addSlsDetector(const char *name, int pos) {
detectorType t=GENERIC; detectorType t=getDetectorType(string(name));
int online=0;
slsDetector *s=NULL; slsDetector *s=NULL;
int id; int id;
#ifdef VERBOSE #ifdef VERBOSE
@ -456,60 +523,101 @@ int multiSlsDetector::addSlsDetector(char *name, int pos) {
#endif #endif
for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) { if (t==GENERIC) {
if (detectors[i]) { for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) {
if (detectors[i]->getHostname()==string(name)) { if (detectors[i]) {
cout << "Detector " << name << "already part of the multiDetector in position " << i << "!" << endl<< "Remove it before adding it back in a new position!"<< endl; if (detectors[i]->getHostname()==string(name)) {
return -1; cout << "Detector " << name << "already part of the multiDetector in position " << i << "!" << endl<< "Remove it before adding it back in a new position!"<< endl;
} return -1;
} }
} }
}
//checking that the detector doesn't already exists //checking that the detector doesn't already exists
for (id=0; id<MAXDET; id++) { for (id=0; id<MAXDET; id++) {
if (slsDetector::exists(id)>0) {
#ifdef VERBOSE #ifdef VERBOSE
cout << id << endl; cout << "Detector " << id << " already exists" << endl;
#endif #endif
if (slsDetector::exists(id)>0) { s=new slsDetector(id);
s=new slsDetector(id); if (s->getHostname()==string(name))
if (s->getHostname()==string(name)) break;
break; delete s;
delete s; s=NULL;
s=NULL; //id++;
id++; }
} }
}
if (s==NULL) { if (s==NULL) {
t=slsDetector::getDetectorType(name, DEFAULT_PORTNO); t=slsDetector::getDetectorType(name, DEFAULT_PORTNO);
if (t==GENERIC) { if (t==GENERIC) {
cout << "Detector " << name << "does not exist in shared memory and could not connect to it to determine the type!" << endl; cout << "Detector " << name << "does not exist in shared memory and could not connect to it to determine the type (which is not specified)!" << endl;
return -1; return -1;
} }
#ifdef VERBOSE #ifdef VERBOSE
else else
cout << "Detector type is " << t << endl; cout << "Detector type is " << t << endl;
#endif
online=1;
}
}
#ifdef VERBOSE
else
cout << "Adding detector by type " << getDetectorType(t) << endl;
#endif #endif
for (id=0; id<MAXDET; id++) {
if (slsDetector::exists(id)==0) {
break;
}
}
s=new slsDetector(t, id);
s->setTCPSocket(name);
delete s;
}
return addSlsDetector(id, pos);
if (s==NULL) {
for (id=0; id<MAXDET; id++) {
if (slsDetector::exists(id)==0) {
break;
}
}
#ifdef VERBOSE
cout << "Creating detector " << id << " of type " << getDetectorType(t) << endl;
#endif
s=new slsDetector(t, id);
if (online)
s->setTCPSocket(name);
delete s;
}
#ifdef VERBOSE
cout << "Adding it to the multi detector structure" << endl;
#endif
return addSlsDetector(id, pos);
}
int multiSlsDetector::addSlsDetector(detectorType t, int pos) {
int id;
if (t==GENERIC) {
return -1;
} }
for (id=0; id<MAXDET; id++) {
if (slsDetector::exists(id)==0) {
break;
}
}
#ifdef VERBOSE
cout << "Creating detector " << id << " of type " << getDetectorType(t) << endl;
#endif
slsDetector *s=new slsDetector(t, id);
#ifdef VERBOSE
cout << "Adding it to the multi detector structure" << endl;
#endif
return addSlsDetector(id, pos);
}
@ -572,33 +680,46 @@ int multiSlsDetector::removeSlsDetector(int pos) {
cout << "Removing detector in position " << pos << endl; cout << "Removing detector in position " << pos << endl;
#endif #endif
if (pos<0 ) int mi=0, ma=thisMultiDetector->numberOfDetectors, single=0;
pos=thisMultiDetector->numberOfDetectors-1;
if (pos>=0) {
mi=pos;
ma=pos+1;
single=1;
}
// if (pos<0 )
// pos=thisMultiDetector->numberOfDetectors-1;
if (pos>=thisMultiDetector->numberOfDetectors) if (pos>=thisMultiDetector->numberOfDetectors)
return thisMultiDetector->numberOfDetectors; return thisMultiDetector->numberOfDetectors;
j=pos; //j=pos;
if (detectors[j]) { for (j=mi; j<ma; j++) {
if (detectors[j]) {
thisMultiDetector->dataBytes-=detectors[j]->getDataBytes(); thisMultiDetector->dataBytes-=detectors[j]->getDataBytes();
thisMultiDetector->numberOfChannels-=detectors[j]->getTotalNumberOfChannels(); thisMultiDetector->numberOfChannels-=detectors[j]->getTotalNumberOfChannels();
thisMultiDetector->maxNumberOfChannels-=detectors[j]->getMaxNumberOfChannels(); thisMultiDetector->maxNumberOfChannels-=detectors[j]->getMaxNumberOfChannels();
delete detectors[j]; delete detectors[j];
thisMultiDetector->numberOfDetectors--; thisMultiDetector->numberOfDetectors--;
if (single) {
for (int i=j+1; i<thisMultiDetector->numberOfDetectors+1; i++) { for (int i=j+1; i<thisMultiDetector->numberOfDetectors+1; i++) {
detectors[i-1]=detectors[i]; detectors[i-1]=detectors[i];
thisMultiDetector->detectorIds[i-1]=thisMultiDetector->detectorIds[i]; thisMultiDetector->detectorIds[i-1]=thisMultiDetector->detectorIds[i];
}
detectors[thisMultiDetector->numberOfDetectors]=NULL;
thisMultiDetector->detectorIds[thisMultiDetector->numberOfDetectors]=-1;
}
} }
detectors[thisMultiDetector->numberOfDetectors]=NULL;
thisMultiDetector->detectorIds[thisMultiDetector->numberOfDetectors]=-1;
} }
return thisMultiDetector->numberOfDetectors; return thisMultiDetector->numberOfDetectors;
} }
@ -2947,7 +3068,7 @@ int multiSlsDetector::readConfigurationFile(string const fname){
slsDetectorCommand *cmd=new slsDetectorCommand(this); multiSlsDetectorClient *cmd;
char ext[100]; char ext[100];
@ -3001,27 +3122,25 @@ int multiSlsDetector::readConfigurationFile(string const fname){
strcpy(args[iargval],sargname.c_str()); strcpy(args[iargval],sargname.c_str());
iargval++; iargval++;
//} //}
} }
ans=cmd->executeLine(iargval,args,PUT_ACTION); cmd=new multiSlsDetectorClient(iargval, args, PUT_ACTION, this);
#ifdef VERBOSE delete cmd;
std::cout<< ans << std::endl;
#endif
} }
iline++; iline++;
} }
infile.close(); infile.close();
for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) { // for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) {
sprintf(ext,".det%d",i); // sprintf(ext,".det%d",i);
if (detectors[i]) { // if (detectors[i]) {
detectors[i]->readConfigurationFile(fname+string(ext)); // detectors[i]->readConfigurationFile(fname+string(ext));
} // }
} // }
@ -3038,7 +3157,6 @@ int multiSlsDetector::readConfigurationFile(string const fname){
#endif #endif
delete cmd;
return iline; return iline;
@ -3053,15 +3171,10 @@ int multiSlsDetector::writeConfigurationFile(string const fname){
slsDetectorCommand *cmd=new slsDetectorCommand(this);
string names[]={ \ string names[]={ \
"hostname", \ "type", \
"master", \ "master", \
"sync", \ "sync", \
"caldir", \
"settingsdir", \
"trimen", \
"outdir", \ "outdir", \
"ffdir", \ "ffdir", \
"headerbefore", \ "headerbefore", \
@ -3075,7 +3188,7 @@ int multiSlsDetector::writeConfigurationFile(string const fname){
"binsize", \ "binsize", \
"threaded" }; "threaded" };
int nvar=18; int nvar=15;
char ext[100]; char ext[100];
@ -3095,33 +3208,43 @@ int multiSlsDetector::writeConfigurationFile(string const fname){
outfile.open(fname.c_str(),ios_base::out); outfile.open(fname.c_str(),ios_base::out);
if (outfile.is_open()) { if (outfile.is_open()) {
for (iv=0; iv<nvar; iv++) {
slsDetectorCommand *cmd=new slsDetectorCommand(this);
// detector types!!!
strcpy(args[0],names[iv].c_str());
outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl;
// single detector configuration
for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) {
// sprintf(ext,".det%d",i);
if (detectors[i]) {
iv+=detectors[i]->writeConfigurationFile(outfile,i);
}
}
//other configurations
for (iv=1; iv<nvar; iv++) {
strcpy(args[0],names[iv].c_str()); strcpy(args[0],names[iv].c_str());
outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl; outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl;
} }
outfile.close();
delete cmd;
for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) { outfile.close();
sprintf(ext,".det%d",i); } else {
if (detectors[i]) {
detectors[i]->writeConfigurationFile(fname+string(ext));
}
}
}
else {
std::cout<< "Error opening configuration file " << fname << " for writing" << std::endl; std::cout<< "Error opening configuration file " << fname << " for writing" << std::endl;
return FAIL; return FAIL;
} }
#ifdef VERBOSE #ifdef VERBOSE
std::cout<< "wrote " <<ret << " lines to configuration file " << std::endl; std::cout<< "wrote " <<ret << " lines to configuration file " << std::endl;
#endif #endif
delete cmd;
return iv; return iv;
}; };
@ -3245,7 +3368,6 @@ int multiSlsDetector::dumpDetectorSetup(string const fname, int level){
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl; outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++; iv++;
outfile.close();
@ -3253,10 +3375,11 @@ int multiSlsDetector::dumpDetectorSetup(string const fname, int level){
for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) { for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) {
sprintf(ext,".det%d",i); sprintf(ext,".det%d",i);
if (detectors[i]) { if (detectors[i]) {
detectors[i]->dumpDetectorSetup(fname+string(ext), level); iv+=detectors[i]->dumpDetectorSetup(fname+string(ext),outfile, level, i);
} }
} }
outfile.close();
} }
else { else {
std::cout<< "Error opening parameters file " << fname1 << " for writing" << std::endl; std::cout<< "Error opening parameters file " << fname1 << " for writing" << std::endl;
@ -3279,7 +3402,7 @@ int multiSlsDetector::retrieveDetectorSetup(string const fname1, int level){
slsDetectorCommand *cmd=new slsDetectorCommand(this); multiSlsDetectorClient *cmd;
char ext[100]; char ext[100];
@ -3297,8 +3420,8 @@ int multiSlsDetector::retrieveDetectorSetup(string const fname1, int level){
int iline=0; int iline=0;
if (level==2) { if (level==2) {
fname=fname1+string(".config"); // fname=fname1+string(".config");
readConfigurationFile(fname); // readConfigurationFile(fname);
#ifdef VERBOSE #ifdef VERBOSE
cout << "config file read" << endl; cout << "config file read" << endl;
#endif #endif
@ -3336,7 +3459,7 @@ int multiSlsDetector::retrieveDetectorSetup(string const fname1, int level){
// } // }
} }
if (level==2) { if (level==2) {
cmd->executeLine(iargval,args,PUT_ACTION); cmd=new multiSlsDetectorClient(iargval,args,PUT_ACTION,this);
} else { } else {
if (string(args[0])==string("flatfield")) if (string(args[0])==string("flatfield"))
; ;
@ -3347,8 +3470,7 @@ int multiSlsDetector::retrieveDetectorSetup(string const fname1, int level){
else if (string(args[0])==string("trimbits")) else if (string(args[0])==string("trimbits"))
; ;
else { else {
; cmd=new multiSlsDetectorClient(iargval,args,PUT_ACTION,this);
cmd->executeLine(iargval,args,PUT_ACTION);
} }
} }
} }
@ -3358,12 +3480,12 @@ int multiSlsDetector::retrieveDetectorSetup(string const fname1, int level){
for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) { // for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) {
sprintf(ext,".det%d",i); // sprintf(ext,".det%d",i);
if (detectors[i]) { // if (detectors[i]) {
detectors[i]->retrieveDetectorSetup(fname1+string(ext), level); // detectors[i]->retrieveDetectorSetup(fname1+string(ext), level);
} // }
} // }
} else { } else {
@ -3373,7 +3495,6 @@ int multiSlsDetector::retrieveDetectorSetup(string const fname1, int level){
#ifdef VERBOSE #ifdef VERBOSE
std::cout<< "Read " << iline << " lines" << std::endl; std::cout<< "Read " << iline << " lines" << std::endl;
#endif #endif
delete cmd;
return iline; return iline;

View File

@ -242,7 +242,9 @@ class multiSlsDetector : public slsDetectorUtils {
\param name of the detector to be added (should already exist in shared memory or at least be online) \param name of the detector to be added (should already exist in shared memory or at least be online)
\param pos position where it should be added (normally at the end of the list (default to -1) \param pos position where it should be added (normally at the end of the list (default to -1)
\return the actual number of detectors or -1 if it failed*/ \return the actual number of detectors or -1 if it failed*/
int addSlsDetector(char *name, int pos=-1); int addSlsDetector(const char *name, int pos=-1);
int addSlsDetector(detectorType type, int pos=-1);
/**removes the detector in position pos from the multidetector /**removes the detector in position pos from the multidetector
\param pos position of the detector to be removed from the multidetector system (defaults to -1 i.e. last detector) \param pos position of the detector to be removed from the multidetector system (defaults to -1 i.e. last detector)
@ -259,12 +261,18 @@ class multiSlsDetector : public slsDetectorUtils {
string setHostname(char*, int pos=-1); string setHostname(const char*, int pos=-1);
string getHostname(int pos=-1); string getHostname(int pos=-1);
detectorType getDetectorsType(int pos=-1); detectorType getDetectorsType(int pos=-1);
detectorType setDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){addSlsDetector(type, pos); return getDetectorsType(pos);};
string sgetDetectorsType(int pos=-1);
string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(setDetectorsType(type, pos));}; //
string ssetDetectorsType(string s, int pos=-1);//{return getDetectorType(setDetectorsType(getDetectorType(s),pos));}; // should decode detector type
/** adds a detector by id in position pos /** adds a detector by id in position pos
@ -988,6 +996,9 @@ class multiSlsDetector : public slsDetectorUtils {
int getMoveFlag(int imod); int getMoveFlag(int imod);
slsDetector *getSlsDetector(int pos) {if (pos>=0 && pos< MAXDET) return detectors[pos]; return NULL;};
protected: protected:

View File

@ -0,0 +1,84 @@
#include <iostream>
#include <string>
#include "multiSlsDetector.h"
#include "multiSlsDetectorCommand.h"
#include <stdlib.h>
using namespace std;
class multiSlsDetectorClient {
public:
multiSlsDetectorClient(int argc, char *argv[], int action, multiSlsDetector *myDetector=NULL) { \
string answer; \
multiSlsDetectorCommand *myCmd; \
int del=0; \
if (argc==0 && action==slsDetectorDefs::READOUT_ACTION) { \
if (myDetector==NULL) { \
myDetector=new multiSlsDetector(); \
del=1; \
};
myCmd=new multiSlsDetectorCommand(myDetector); \
answer=myCmd->executeLine(argc, argv, action); \
cout << answer<< endl; \
delete myCmd; \
if (del) delete myDetector; \
return; \
}; \
int id=-1, iv=0, pos=-1; \
char *c; \
char cmd[100]; \
if (action==slsDetectorDefs::PUT_ACTION && argc<2) { \
cout << "Wrong usage - should be: "<< argv[0] << "[id-][pos:]channel arg" << endl; \
cout << endl; \
return; \
};
if (action==slsDetectorDefs::GET_ACTION && argc<1) { \
cout << "Wrong usage - should be: "<< argv[0] << "[id-][pos:]channel arg" << endl; \
cout << endl; \
return; \
}; \
if (myDetector==NULL) {
iv=sscanf(argv[0],"%d-%s",&id, cmd); \
if (iv==2 && id>=0) { \
myDetector=new multiSlsDetector(id); \
argv[0]=cmd; \
cout << id << "-" ; \
} else { \
myDetector=new multiSlsDetector(); \
};
del=1;
} \
iv=sscanf(argv[0],"%d:%s",&pos, cmd); \
if (iv==2 && pos>=0) { \
argv[0]=cmd; \
cout << pos << ":" ; \
} ; \
myCmd=new multiSlsDetectorCommand(myDetector); \
answer=myCmd->executeLine(argc, argv, action, pos); \
cout << argv[0] << " " ; \
cout << answer<< endl; \
delete myCmd; \
if (del) delete myDetector; \
};
};

View File

@ -0,0 +1,58 @@
#ifndef MULTI_SLS_DETECTOR_COMMAND_H
#define MULTI_SLS_DETECTOR_COMMAND_H
#include "slsDetector.h"
#include "multiSlsDetector.h"
#include "slsDetectorCommand.h"
using namespace std;
/** @short This class handles the command line I/Os, help etc. of the text clients */
class multiSlsDetectorCommand : public slsDetectorCommand {
public:
multiSlsDetectorCommand(multiSlsDetector *det) : slsDetectorCommand(det) {myDet=det;};
/* /\** */
/* executes a set of string arguments according to a given format. It is used to read/write configuration file, dump and retrieve detector settings and for the command line interface command parsing */
/* \param narg number of arguments */
/* \param args array of string arguments */
/* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */
/* \returns answer string */
/* *\/ */
string executeLine(int narg, char *args[], int action, int id=-1) { \
string s; \
if (id>=0) {
slsDetector *d=myDet->getSlsDetector(id); \
if (d) { \
slsDetectorCommand *cmd=new slsDetectorCommand(d); \
s=cmd->executeLine(narg, args, action); \
delete cmd;
} else s=string("detector does no exist"); \
} else \
s=slsDetectorCommand::executeLine(narg,args,action); \
return s;
};
private:
multiSlsDetector *myDet;
};
#endif

View File

@ -103,6 +103,10 @@ int initDetector() {
dynamicRange=getDynamicRange(); dynamicRange=getDynamicRange();
nModX=setNMod(-1); nModX=setNMod(-1);
//dataBytes=nModX*NCHIP*NCHAN*4; //dataBytes=nModX*NCHIP*NCHAN*4;
// dynamicRange=32; // dynamicRange=32;
// initChip(0, 0,ALLMOD); // initChip(0, 0,ALLMOD);

View File

@ -125,6 +125,8 @@ slsDetector::slsDetector(int id) :slsDetectorUtils(),
{ {
detectorType type=(detectorType)getDetectorType(id); detectorType type=(detectorType)getDetectorType(id);
while (shmId<0) { while (shmId<0) {
@ -220,7 +222,6 @@ slsDetector::slsDetector(char *name, int id, int cport) : slsDetectorUtils(),
chipregs(NULL), chipregs(NULL),
chanregs(NULL) chanregs(NULL)
{ {
detectorType type=(detectorType)getDetectorType(name, cport); detectorType type=(detectorType)getDetectorType(name, cport);
@ -252,7 +253,7 @@ slsDetector::slsDetector(char *name, int id, int cport) : slsDetectorUtils(),
} }
slsDetectorDefs::detectorType slsDetector::getDetectorType(char *name, int cport) { slsDetectorDefs::detectorType slsDetector::getDetectorType(const char *name, int cport) {
int retval=FAIL; int retval=FAIL;
detectorType t=GENERIC; detectorType t=GENERIC;
@ -433,9 +434,14 @@ slsDetectorDefs::detectorType slsDetector::getDetectorType(int id) {
int slsDetector::initializeDetectorSize(detectorType type) { int slsDetector::initializeDetectorSize(detectorType type) {
char *goff; char *goff;
goff=(char*)thisDetector; goff=(char*)thisDetector;
// cout << "init detector size" << endl;
/** if the shared memory has newly be created, initialize the detector variables */ /** if the shared memory has newly be created, initialize the detector variables */
if (thisDetector->alreadyExisting==0) { if (thisDetector->alreadyExisting==0) {
// cout << "detector not existing " << endl;
/** set hostname to default */ /** set hostname to default */
strcpy(thisDetector->hostname,DEFAULT_HOSTNAME); strcpy(thisDetector->hostname,DEFAULT_HOSTNAME);
@ -464,6 +470,7 @@ int slsDetector::initializeDetectorSize(detectorType type) {
thisDetector->nModMax[Y]=1; thisDetector->nModMax[Y]=1;
thisDetector->dynamicRange=24; thisDetector->dynamicRange=24;
thisDetector->moveFlag=1; thisDetector->moveFlag=1;
cout << "move flag" << thisDetector->moveFlag<< endl;
break; break;
case PICASSO: case PICASSO:
thisDetector->nChans=128; thisDetector->nChans=128;
@ -620,35 +627,6 @@ int slsDetector::initializeDetectorSize(detectorType type) {
#endif #endif
// getPointers(&thisDetector->stoppedFlag, \
// &thisDetector->threadedProcessing, \
// &thisDetector->actionMask, \
// thisDetector->actionScript, \
// thisDetector->actionParameter, \
// thisDetector->nScanSteps, \
// thisDetector->scanMode, \
// thisDetector->scanScript, \
// thisDetector->scanParameter, \
// thisDetector->scanSteps, \
// thisDetector->scanPrecision, \
// &thisDetector->numberOfPositions, \
// thisDetector->detPositions, \
// thisDetector->angConvFile, \
// &thisDetector->correctionMask, \
// &thisDetector->binSize, \
// &thisDetector->fineOffset, \
// &thisDetector->globalOffset, \
// &thisDetector->angDirection, \
// thisDetector->flatFieldDir, \
// thisDetector->flatFieldFile, \
// thisDetector->badChanFile, \
// thisDetector->timerValue, \
// &thisDetector->currentSettings, \
// &thisDetector->currentThresholdEV, \
// thisDetector->filePath, \
// thisDetector->fileName, \
// &thisDetector->fileIndex);
stoppedFlag=&thisDetector->stoppedFlag; stoppedFlag=&thisDetector->stoppedFlag;
threadedProcessing=&thisDetector->threadedProcessing; threadedProcessing=&thisDetector->threadedProcessing;
actionMask=&thisDetector->actionMask; actionMask=&thisDetector->actionMask;
@ -686,21 +664,15 @@ int slsDetector::initializeDetectorSize(detectorType type) {
#ifdef VERBOSE #ifdef VERBOSE
cout << "done" << endl; cout << "done" << endl;
#endif #endif
// #ifdef VERBOSE
// cout << "filling bad channel mask" << endl;
// #endif
// /** fill the BadChannelMask \sa fillBadChannelMask */
// fillBadChannelMask();
// #ifdef VERBOSE
// cout << "done" << endl;
// #endif
/** modifies the last PID accessing the detector */ /** modifies the last PID accessing the detector */
thisDetector->lastPID=getpid(); thisDetector->lastPID=getpid();
#ifdef VERBOSE #ifdef VERBOSE
cout << "Det size initialized " << endl; cout << "Det size initialized " << endl;
#endif #endif
return OK; return OK;
} }
@ -4915,7 +4887,7 @@ int slsDetector::writeConfigurationFile(string const fname){
} }
int slsDetector::writeConfigurationFile(ofstream &outfile){ int slsDetector::writeConfigurationFile(ofstream &outfile, int id){
slsDetectorCommand *cmd=new slsDetectorCommand(this); slsDetectorCommand *cmd=new slsDetectorCommand(this);
int nvar; int nvar;
@ -4938,6 +4910,8 @@ int slsDetector::writeConfigurationFile(ofstream &outfile){
"nmod", \ "nmod", \
"badchannels", \ "badchannels", \
"angconv", \ "angconv", \
"angdir", \
"moveflag", \
"globaloff", \ "globaloff", \
"binsize", \ "binsize", \
"threaded", \ "threaded", \
@ -4957,7 +4931,7 @@ int slsDetector::writeConfigurationFile(ofstream &outfile){
case MYTHEN: case MYTHEN:
nsig=4; nsig=4;
default: default:
nvar=23; nvar=25;
} }
@ -4969,14 +4943,19 @@ int slsDetector::writeConfigurationFile(ofstream &outfile){
for (iv=0; iv<nvar; iv++) { for (iv=0; iv<nvar; iv++) {
cout << iv << " " << names[iv] << endl; // cout << iv << " " << names[iv] << endl;
if (names[iv]=="extsig") { if (names[iv]=="extsig") {
for (int is=0; is<nsig; is++) { for (int is=0; is<nsig; is++) {
sprintf(args[0],"%s:%d",names[iv].c_str(),is); sprintf(args[0],"%s:%d",names[iv].c_str(),is);
if (id>=0)
outfile << id << ":";
outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl; outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl;
} }
} else { } else {
strcpy(args[0],names[iv].c_str()); strcpy(args[0],names[iv].c_str());
if (id>=0)
outfile << id << ":";
outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl; outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl;
} }
} }
@ -5001,7 +4980,7 @@ int slsDetector::writeConfigurationFile(ofstream &outfile){
It should be possible to dump all the settings of the detector (including trimbits, threshold energy, gating/triggering, acquisition time etc. It should be possible to dump all the settings of the detector (including trimbits, threshold energy, gating/triggering, acquisition time etc.
in a file and retrieve it for repeating the measurement with identicals settings, if necessary in a file and retrieve it for repeating the measurement with identicals settings, if necessary
*/ */
int slsDetector::dumpDetectorSetup(string const fname, int level){ int slsDetector::dumpDetectorSetup(string const fname, ofstream &outfile, int level, int id){
slsDetectorCommand *cmd=new slsDetectorCommand(this); slsDetectorCommand *cmd=new slsDetectorCommand(this);
string names[]={ string names[]={
"fname",\ "fname",\
@ -5049,7 +5028,6 @@ int slsDetector::dumpDetectorSetup(string const fname, int level){
int nvar=41; int nvar=41;
int iv=0; int iv=0;
string fname1; string fname1;
ofstream outfile;
char *args[2]; char *args[2];
for (int ia=0; ia<2; ia++) { for (int ia=0; ia<2; ia++) {
args[ia]=new char[1000]; args[ia]=new char[1000];
@ -5061,71 +5039,127 @@ int slsDetector::dumpDetectorSetup(string const fname, int level){
nargs=1; nargs=1;
if (level==2) { if (level==2) {
fname1=fname+string(".config"); fname1=fname+string(".config");
writeConfigurationFile(fname1); strcpy(args[0],"config");
strcpy(args[1],fname1.c_str());
if (id>=0)
outfile << id << ":";
outfile << names[iv] << " " << cmd->executeLine(2,args,GET_ACTION) << std::endl;
iv++;
}
for (iv=0; iv<nvar-5; iv++) {
strcpy(args[0],names[iv].c_str());
if (id>=0)
outfile << id << ":";
outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl;
iv++;
}
strcpy(args[0],names[iv].c_str());
if (level==2) {
fname1=fname+string(".ff");
strcpy(args[1],fname1.c_str());
}
if (id>=0)
outfile << id << ":";
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
strcpy(args[0],names[iv].c_str());
if (level==2) {
fname1=fname+string(".bad");
strcpy(args[1],fname1.c_str());
}
if (id>=0)
outfile << id << ":";
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
strcpy(args[0],names[iv].c_str());
if (level==2) {
fname1=fname+string(".angoff");
strcpy(args[1],fname1.c_str());
}
if (id>=0)
outfile << id << ":";
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
strcpy(args[0],names[iv].c_str());
if (level==2) {
size_t c=fname.rfind('/');
if (c<string::npos) {
fname1=fname.substr(0,c+1)+string("trim_")+fname.substr(c+1);
} else {
fname1=string("trim_")+fname;
}
strcpy(args[1],fname1.c_str());
#ifdef VERBOSE
std::cout<< "writing to file " << fname1 << std::endl;
#endif
}
if (id>=0)
outfile << id << ":";
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
strcpy(args[0],names[iv].c_str());
// for (int is=0; is<4; is++) {
// sprintf(args[0],"%s:%d",names[iv].c_str(),is);
if (id>=0)
outfile << id << ":";
outfile << args[0] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl;
// }
iv++;
delete cmd;
return 0;
}
/*
It should be possible to dump all the settings of the detector (including trimbits, threshold energy, gating/triggering, acquisition time etc.
in a file and retrieve it for repeating the measurement with identicals settings, if necessary
*/
int slsDetector::dumpDetectorSetup(string const fname, int level){
string fname1;
ofstream outfile;
if (level==2) {
fname1=fname+string(".det"); fname1=fname+string(".det");
} else } else
fname1=fname; fname1=fname;
outfile.open(fname1.c_str(),ios_base::out); outfile.open(fname1.c_str(),ios_base::out);
if (outfile.is_open()) { if (outfile.is_open()) {
for (iv=0; iv<nvar-5; iv++) {
strcpy(args[0],names[iv].c_str());
outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl;
}
dumpDetectorSetup(fname, outfile, level);
strcpy(args[0],names[iv].c_str());
if (level==2) {
fname1=fname+string(".ff");
strcpy(args[1],fname1.c_str());
}
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
strcpy(args[0],names[iv].c_str());
if (level==2) {
fname1=fname+string(".bad");
strcpy(args[1],fname1.c_str());
}
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
strcpy(args[0],names[iv].c_str());
if (level==2) {
fname1=fname+string(".angoff");
strcpy(args[1],fname1.c_str());
}
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
strcpy(args[0],names[iv].c_str());
if (level==2) {
size_t c=fname.rfind('/');
if (c<string::npos) {
fname1=fname.substr(0,c+1)+string("trim_")+fname.substr(c+1);
} else {
fname1=string("trim_")+fname;
}
strcpy(args[1],fname1.c_str());
#ifdef VERBOSE
std::cout<< "writing to file " << fname1 << std::endl;
#endif
}
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
strcpy(args[0],names[iv].c_str());
// for (int is=0; is<4; is++) {
// sprintf(args[0],"%s:%d",names[iv].c_str(),is);
outfile << args[0] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl;
// }
iv++;
outfile.close(); outfile.close();
} } else {
else {
std::cout<< "Error opening parameters file " << fname1 << " for writing" << std::endl; std::cout<< "Error opening parameters file " << fname1 << " for writing" << std::endl;
return FAIL; return FAIL;
} }
@ -5133,12 +5167,55 @@ int slsDetector::dumpDetectorSetup(string const fname, int level){
#ifdef VERBOSE #ifdef VERBOSE
std::cout<< "wrote " <<iv << " lines to "<< fname1 << std::endl; std::cout<< "wrote " <<iv << " lines to "<< fname1 << std::endl;
#endif #endif
delete cmd;
return 0; return 0;
} }
int slsDetector::retrieveDetectorSetup(string fname1, int level){ int slsDetector::retrieveDetectorSetup(string fname1, int level){

View File

@ -270,11 +270,8 @@ typedef struct sharedSlsDetector {
*/ */
slsDetector(detectorType type=GENERIC, int id=0); slsDetector(detectorType type=GENERIC, int id=0);
/** constructor /** constructor
\param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently \param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently
*/ */
slsDetector(int id); slsDetector(int id);
@ -321,8 +318,7 @@ typedef struct sharedSlsDetector {
*/ */
int writeConfigurationFile(string const fname); int writeConfigurationFile(string const fname);
int writeConfigurationFile(ofstream &outfile); int writeConfigurationFile(ofstream &outfile, int id=-1);
@ -336,6 +332,9 @@ typedef struct sharedSlsDetector {
*/ */
int dumpDetectorSetup(string const fname, int level=0); int dumpDetectorSetup(string const fname, int level=0);
int dumpDetectorSetup(string const fname, ofstream &outfile, int level=0, int id=-1);
/** /**
Loads the detector setup from file Loads the detector setup from file
\param fname file to read from \param fname file to read from
@ -389,7 +388,7 @@ typedef struct sharedSlsDetector {
/** returns the detector hostname \sa sharedSlsDetector */ /** returns the detector hostname \sa sharedSlsDetector */
string getHostname(int ipos=-1) {return string(thisDetector->hostname);}; string getHostname(int ipos=-1) {return string(thisDetector->hostname);};
/** returns the detector hostname \sa sharedSlsDetector */ /** returns the detector hostname \sa sharedSlsDetector */
string setHostname(char *name, int ipos=-1) {setTCPSocket(string(name)); return string(thisDetector->hostname);}; string setHostname(const char *name, int ipos=-1) {setTCPSocket(string(name)); return string(thisDetector->hostname);};
/** connect to the control port */ /** connect to the control port */
int connectControl(); int connectControl();
/** disconnect from the control port */ /** disconnect from the control port */
@ -607,6 +606,12 @@ typedef struct sharedSlsDetector {
*/ */
detectorType getDetectorsType(int pos=-1); detectorType getDetectorsType(int pos=-1);
detectorType setDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorsType(pos);};
string sgetDetectorsType(int pos=-1){return getDetectorType(getDetectorsType(pos));};
string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(getDetectorsType(pos));};
string ssetDetectorsType(string t, int pos=-1){return getDetectorType(getDetectorsType(pos));}
// Detector configuration functions // Detector configuration functions
/** /**
@ -1255,7 +1260,7 @@ typedef struct sharedSlsDetector {
\param \param
\param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition)
*/ */
static detectorType getDetectorType(char *name, int cport=DEFAULT_PORTNO); static detectorType getDetectorType(const char *name, int cport=DEFAULT_PORTNO);
/** /**
returns the detector type from hostname and controlport returns the detector type from hostname and controlport
@ -1338,6 +1343,8 @@ typedef struct sharedSlsDetector {
int getMoveFlag(int imod){if (moveFlag) return *moveFlag; else return 1;}; int getMoveFlag(int imod){if (moveFlag) return *moveFlag; else return 1;};
/** Frees the shared memory - should not be used*/
int freeSharedMemory();
protected: protected:
@ -1401,8 +1408,6 @@ typedef struct sharedSlsDetector {
*/ */
int initSharedMemory(detectorType type=GENERIC, int id=0); int initSharedMemory(detectorType type=GENERIC, int id=0);
/** Frees the shared memory - should not be used*/
int freeSharedMemory();
/** /**
Initializes the thisDetector structure Initializes the thisDetector structure
\param type is needed to define the number of channels, chips, modules etc. \param type is needed to define the number of channels, chips, modules etc.

View File

@ -53,6 +53,10 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) {
i++; i++;
descrToFuncMap[i].m_pFuncName="type"; //OK
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname;
i++;
descrToFuncMap[i].m_pFuncName="hostname"; //OK descrToFuncMap[i].m_pFuncName="hostname"; //OK
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname; descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname;
i++; i++;
@ -929,23 +933,44 @@ string slsDetectorCommand::cmdHostname(int narg, char *args[], int action){
if (vvstr.fail()) if (vvstr.fail())
ivar=-1; ivar=-1;
} }
p=string(args[0]).find("hostname");
if (action==PUT_ACTION) { if (p==string::npos) {
//add by hostname //type
if (ivar==-1) { // cout << "should add by type!" << endl;
strcpy(hostname,"");
for (int id=1; id<narg; id++) { if (action==PUT_ACTION) {
strcat(hostname,args[id]); //add by type
if(narg>2) if (ivar==-1) {
strcat(hostname,"+"); strcpy(hostname,"");
} for (int id=1; id<narg; id++) {
} else strcat(hostname,args[id]);
strcpy(hostname,args[1]); if(narg>2)
myDet->setHostname(hostname, ivar); strcat(hostname,"+");
} }
} else
return string(myDet->getHostname(ivar)); strcpy(hostname,args[1]);
myDet->ssetDetectorsType(hostname, ivar);
}
return myDet->sgetDetectorsType(ivar);
} else {
if (action==PUT_ACTION) {
//add by hostname
if (ivar==-1) {
strcpy(hostname,"");
for (int id=1; id<narg; id++) {
strcat(hostname,args[id]);
if(narg>2)
strcat(hostname,"+");
}
} else
strcpy(hostname,args[1]);
myDet->setHostname(hostname, ivar);
}
return string(myDet->getHostname(ivar));
}
} }

View File

@ -11,7 +11,7 @@ using namespace std;
/** @short This class handles the command line I/Os, help etc. of the text clients */ /** @short This class handles the command line I/Os, help etc. of the text clients */
class slsDetectorCommand : public slsDetectorDefs { class slsDetectorCommand : public virtual slsDetectorDefs {
public: public:
@ -26,7 +26,7 @@ class slsDetectorCommand : public slsDetectorDefs {
/* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */ /* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */
/* \returns answer string */ /* \returns answer string */
/* *\/ */ /* *\/ */
string executeLine(int narg, char *args[], int action=HELP_ACTION); virtual string executeLine(int narg, char *args[], int action);
/* /\** */ /* /\** */
/* returns the help for the executeLine command */ /* returns the help for the executeLine command */

View File

@ -107,7 +107,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing {
\param pos position in the multi detector structure (is -1 expects concatenated hostnames divided by a +) \param pos position in the multi detector structure (is -1 expects concatenated hostnames divided by a +)
\returns hostname \returns hostname
*/ */
virtual string setHostname(char* name, int pos=-1)=0; virtual string setHostname(const char* name, int pos=-1)=0;
/** returns the detector type /** returns the detector type
@ -116,6 +116,20 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing {
*/ */
virtual detectorType getDetectorsType(int pos=-1)=0; virtual detectorType getDetectorsType(int pos=-1)=0;
/** returns the detector type
\param pos position in the multi detector structure (is -1 returns type of detector with id -1)
\returns type
*/
virtual string sgetDetectorsType(int pos=-1)=0;
/** returns the detector type
\param pos position in the multi detector structure (is -1 returns type of detector with id -1)
\returns type
*/
virtual detectorType setDetectorsType(detectorType t=GET_DETECTOR_TYPE, int pos=-1)=0;
virtual string ssetDetectorsType(detectorType t=GET_DETECTOR_TYPE, int pos=-1)=0;
virtual string ssetDetectorsType(string s, int pos=-1)=0;
/** Gets the detector id (shared memory id) of an slsDetector /** Gets the detector id (shared memory id) of an slsDetector

View File

@ -431,7 +431,10 @@ float angularConversion::getAngularConversionParameter(angleConversionParameter
case BIN_SIZE: case BIN_SIZE:
return *binSize; return *binSize;
case MOVE_FLAG: case MOVE_FLAG:
return *moveFlag; if (moveFlag)
return *moveFlag;
else
return -1;
default: default:
return 0; return 0;
} }

View File

@ -252,7 +252,7 @@ void postProcessing::doProcessing(float *lfdata, int delflag, string fname) {
#endif #endif
cout << "lock 1" << endl; // cout << "lock 1" << endl;
pthread_mutex_lock(&mp); pthread_mutex_lock(&mp);
if ((getCurrentPositionIndex()>=getNumberOfPositions() && posfinished==1 && queuesize==1)) { if ((getCurrentPositionIndex()>=getNumberOfPositions() && posfinished==1 && queuesize==1)) {
@ -262,7 +262,7 @@ void postProcessing::doProcessing(float *lfdata, int delflag, string fname) {
np=finalizeMerging(); np=finalizeMerging();
/** file writing */ /** file writing */
incrementPositionIndex(); incrementPositionIndex();
cout << "unlock 1" << endl; // cout << "unlock 1" << endl;
pthread_mutex_unlock(&mp); pthread_mutex_unlock(&mp);
@ -283,16 +283,16 @@ void postProcessing::doProcessing(float *lfdata, int delflag, string fname) {
} else { } else {
thisData=new detectorData(getMergedCounts(),getMergedErrors(),getMergedPositions(),getCurrentProgress(),(fname+ext).c_str(),np); thisData=new detectorData(getMergedCounts(),getMergedErrors(),getMergedPositions(),getCurrentProgress(),(fname+ext).c_str(),np);
cout << "lock 2" << endl; // cout << "lock 2" << endl;
pthread_mutex_lock(&mg); pthread_mutex_lock(&mg);
finalDataQueue.push(thisData); finalDataQueue.push(thisData);
cout << "unlock 2" << endl; // cout << "unlock 2" << endl;
pthread_mutex_unlock(&mg); pthread_mutex_unlock(&mg);
} }
cout << "lock 3" << endl; // cout << "lock 3" << endl;
pthread_mutex_lock(&mp); pthread_mutex_lock(&mp);
} }
cout << "unlock 3" << endl; // cout << "unlock 3" << endl;
pthread_mutex_unlock(&mp); pthread_mutex_unlock(&mp);
if (ffcdata) if (ffcdata)