Commit 7bd8d2ef authored by Yuelong Yu's avatar Yuelong Yu
Browse files

modification on agipd and agipdmaster tango servers

- added frames per file. Frames stored in one file can be configured
- added temperature,udp mac addr, udp ip addr into nexus meta data
parent 5297f864
*.swp
obj
bin
build
usr
......@@ -55,6 +55,7 @@ static const char *RcsId = "$Id: $";
// StopAcq | stop_acq
// Reset | reset
// LoadBunchStructure | load_bunch_structure
// ConnectUc | connect_uc
//================================================================
//================================================================
......@@ -89,6 +90,8 @@ static const char *RcsId = "$Id: $";
// Mask | Tango::DevString Scalar
// BunchStructureFile | Tango::DevString Scalar
// TriggerMode | Tango::DevUShort Scalar
// FramesPerFile | Tango::DevULong Scalar
// MicroController | Tango::DevString Scalar
// LiveDataAnalog | Tango::DevShort Image ( max = 1024 x 1024)
// LiveDataDigital | Tango::DevShort Image ( max = 1024 x 1024)
//================================================================
......@@ -160,6 +163,8 @@ void AGIPD::delete_device()
int* nRet;
m_thAcq->join((void**)&nRet);
delete m_objUC;
/*----- PROTECTED REGION END -----*/ // AGIPD::delete_device
delete[] attr_ADCLatency_read;
delete[] attr_ADCTrigger_read;
......@@ -190,6 +195,8 @@ void AGIPD::delete_device()
delete[] attr_Mask_read;
delete[] attr_BunchStructureFile_read;
delete[] attr_TriggerMode_read;
delete[] attr_FramesPerFile_read;
delete[] attr_MicroController_read;
delete[] attr_LiveDataAnalog_read;
delete[] attr_LiveDataDigital_read;
}
......@@ -242,9 +249,10 @@ void AGIPD::init_device()
attr_Mask_read = new Tango::DevString[1];
attr_BunchStructureFile_read = new Tango::DevString[1];
attr_TriggerMode_read = new Tango::DevUShort[1];
attr_FramesPerFile_read = new Tango::DevULong[1];
attr_MicroController_read = new Tango::DevString[1];
attr_LiveDataAnalog_read = new Tango::DevShort[1024*1024];
attr_LiveDataDigital_read = new Tango::DevShort[1024*1024];
/*----- PROTECTED REGION ID(AGIPD::init_device) ENABLED START -----*/
// Initialize parameters
......@@ -294,6 +302,8 @@ void AGIPD::init_device()
*attr_FilePrefix_read = Tango::DevString("test");
*attr_FileStartNum_read = 0;
*attr_FilePostfix_read = Tango::DevString("nxs");
*attr_FramesPerFile_read = 10000;
if(uDPMACAddr.empty())
cout<<"uDPMACAddr:"<<uDPMACAddr<<"uDPPort:"<<uDPPort<<"uDPIP:"<<uDPIP<<endl
......@@ -318,6 +328,12 @@ void AGIPD::init_device()
if(isMaster==0)
m_thAcq = new AcquisitionThread(this,m_objSys,m_mtxAcq);
//RefreshDetector();
if(ConnectUC(microcontroller))
*attr_MicroController_read = CORBA::string_dup(microcontroller.c_str());
else
*attr_MicroController_read = Tango::DevString("NOT CONNECTED");
set_state(Tango::OFF);
}
else if(simulationMode == 1)
......@@ -368,6 +384,8 @@ void AGIPD::get_device_property()
dev_prop.push_back(Tango::DbDatum("UDPSrcIP"));
dev_prop.push_back(Tango::DbDatum("UDPSrcMAC"));
dev_prop.push_back(Tango::DbDatum("IsMaster"));
dev_prop.push_back(Tango::DbDatum("Microcontroller"));
dev_prop.push_back(Tango::DbDatum("ModuleIDInUc"));
// is there at least one property to be read ?
if (dev_prop.size()>0)
......@@ -503,6 +521,28 @@ void AGIPD::get_device_property()
// And try to extract IsMaster value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> isMaster;
// Try to initialize Microcontroller from class property
cl_prop = ds_class->get_class_property(dev_prop[++i].name);
if (cl_prop.is_empty()==false) cl_prop >> microcontroller;
else {
// Try to initialize Microcontroller from default device value
def_prop = ds_class->get_default_device_property(dev_prop[i].name);
if (def_prop.is_empty()==false) def_prop >> microcontroller;
}
// And try to extract Microcontroller value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> microcontroller;
// Try to initialize ModuleIDInUc from class property
cl_prop = ds_class->get_class_property(dev_prop[++i].name);
if (cl_prop.is_empty()==false) cl_prop >> moduleIDInUc;
else {
// Try to initialize ModuleIDInUc from default device value
def_prop = ds_class->get_default_device_property(dev_prop[i].name);
if (def_prop.is_empty()==false) def_prop >> moduleIDInUc;
}
// And try to extract ModuleIDInUc value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> moduleIDInUc;
}
/*----- PROTECTED REGION ID(AGIPD::get_device_property_after) ENABLED START -----*/
......@@ -520,7 +560,7 @@ void AGIPD::get_device_property()
//--------------------------------------------------------
void AGIPD::always_executed_hook()
{
INFO_STREAM << "AGIPD::always_executed_hook() " << device_name << endl;
DEBUG_STREAM << "AGIPD::always_executed_hook() " << device_name << endl;
/*----- PROTECTED REGION ID(AGIPD::always_executed_hook) ENABLED START -----*/
// code always executed before all requests
......@@ -1761,6 +1801,63 @@ void AGIPD::write_TriggerMode(Tango::WAttribute &attr)
/*----- PROTECTED REGION END -----*/ // AGIPD::write_TriggerMode
}
//--------------------------------------------------------
/**
* Read attribute FramesPerFile related method
* Description: The frames stored in one nexus file.
*
* Data type: Tango::DevULong
* Attr type: Scalar
*/
//--------------------------------------------------------
void AGIPD::read_FramesPerFile(Tango::Attribute &attr)
{
DEBUG_STREAM << "AGIPD::read_FramesPerFile(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AGIPD::read_FramesPerFile) ENABLED START -----*/
// Set the attribute value
attr.set_value(attr_FramesPerFile_read);
/*----- PROTECTED REGION END -----*/ // AGIPD::read_FramesPerFile
}
//--------------------------------------------------------
/**
* Write attribute FramesPerFile related method
* Description: The frames stored in one nexus file.
*
* Data type: Tango::DevULong
* Attr type: Scalar
*/
//--------------------------------------------------------
void AGIPD::write_FramesPerFile(Tango::WAttribute &attr)
{
DEBUG_STREAM << "AGIPD::write_FramesPerFile(Tango::WAttribute &attr) entering... " << endl;
// Retrieve write value
Tango::DevULong w_val;
attr.get_write_value(w_val);
/*----- PROTECTED REGION ID(AGIPD::write_FramesPerFile) ENABLED START -----*/
*attr_FramesPerFile_read = w_val;
/*----- PROTECTED REGION END -----*/ // AGIPD::write_FramesPerFile
}
//--------------------------------------------------------
/**
* Read attribute MicroController related method
* Description: display device name of microcontroller. It is not connected if device is not connected
*
* Data type: Tango::DevString
* Attr type: Scalar
*/
//--------------------------------------------------------
void AGIPD::read_MicroController(Tango::Attribute &attr)
{
DEBUG_STREAM << "AGIPD::read_MicroController(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AGIPD::read_MicroController) ENABLED START -----*/
// Set the attribute value
attr.set_value(attr_MicroController_read);
/*----- PROTECTED REGION END -----*/ // AGIPD::read_MicroController
}
//--------------------------------------------------------
/**
* Read attribute LiveDataAnalog related method
* Description: live image data analog
......@@ -1833,7 +1930,7 @@ Tango::DevState AGIPD::dev_state()
/*----- PROTECTED REGION END -----*/ // AGIPD::dev_state
set_state(argout); // Give the state to Tango.
if (argout!=Tango::ALARM)
DeviceImpl::dev_state();
Tango::DeviceImpl::dev_state();
return get_state(); // Return it after Tango management.
}
//--------------------------------------------------------
......@@ -1876,7 +1973,7 @@ Tango::ConstDevString AGIPD::dev_status()
/*----- PROTECTED REGION END -----*/ // AGIPD::dev_status
set_status(status); // Give the status to Tango.
return DeviceImpl::dev_status(); // Return it.
return Tango::DeviceImpl::dev_status(); // Return it.
}
//--------------------------------------------------------
/**
......@@ -2003,6 +2100,45 @@ void AGIPD::load_bunch_structure()
/*----- PROTECTED REGION END -----*/ // AGIPD::load_bunch_structure
}
//--------------------------------------------------------
/**
* Command ConnectUc related method
* Description: manually connect to microcontroller
*
*/
//--------------------------------------------------------
void AGIPD::connect_uc()
{
DEBUG_STREAM << "AGIPD::ConnectUc() - " << device_name << endl;
/*----- PROTECTED REGION ID(AGIPD::connect_uc) ENABLED START -----*/
// Add your own code
delete m_objUC;
if(ConnectUC(microcontroller))
*attr_MicroController_read = CORBA::string_dup(microcontroller.c_str());
else
*attr_MicroController_read = Tango::DevString("NOT CONNECTED");
/*----- PROTECTED REGION END -----*/ // AGIPD::connect_uc
}
//--------------------------------------------------------
/**
* Method : AGIPD::add_dynamic_commands()
* Description : Create the dynamic commands if any
* for specified device.
*/
//--------------------------------------------------------
void AGIPD::add_dynamic_commands()
{
/*----- PROTECTED REGION ID(AGIPD::add_dynamic_commands) ENABLED START -----*/
// Add your own code to create and add dynamic commands if any
/*----- PROTECTED REGION END -----*/ // AGIPD::add_dynamic_commands
}
/*----- PROTECTED REGION ID(AGIPD::namespace_ending) ENABLED START -----*/
......@@ -2085,7 +2221,33 @@ void AGIPD::load_bunch_structure()
<<"|frame numbers:"<<*attr_FrameNumbers_read
<<"|total frame numbers:"<<m_nTotalFrames<<endl;
}// //--------------------------------------------------------
}
bool AGIPD::ConnectUC(string strUC)
{
try
{
Tango::DeviceProxy* m_objUC = new Tango::DeviceProxy(strUC);
m_objUC->ping();
usleep(100);
return true;
}
catch(std::exception& e)
{
cout<<e.what()<<endl;
}
catch(Tango::DevFailed& df)
{
cout<<"Tango::DevFailed exception during init"<<endl;
for(unsigned int err=0; err<df.errors.length(); err++)
cout<<"Error: " << df.errors[err].desc.in() <<endl;
}
return false;
}
// //--------------------------------------------------------
// /**
// * Read Delay1 attribute
// * Description: delay
......
......@@ -32,6 +32,7 @@
#include <tango.h>
#include<sys/stat.h>
#include <AGIPDInterface.h>
#include <exception>
#include "circularFifo.h"
......@@ -47,7 +48,8 @@ namespace AGIPD_ns
/*----- PROTECTED REGION ID(AGIPD::Additional Class Declarations) ENABLED START -----*/
// Additional Class Declarations
using namespace DetCommonNS;
using namespace DetCommonNS;
using namespace std;
/*----- PROTECTED REGION END -----*/ // AGIPD::Additional Class Declarations
......@@ -66,7 +68,8 @@ class AGIPD : public TANGO_BASE_CLASS
omni_mutex m_mtxSimu;
bool m_bCameraIsBusy;
public:
bool m_bStartAcq;
......@@ -78,9 +81,12 @@ class AGIPD : public TANGO_BASE_CLASS
int m_nSizeY;
short m_shDepth;
int m_nImgSize;
int m_nOpMode;
int m_nTotalFrames;
bool m_bCalibrationMode;
int m_nOpMode;
int m_nTotalFrames;
bool m_bCalibrationMode;
vector<float> m_vTemperature;
Tango::DeviceProxy* m_objUC;
/*----- PROTECTED REGION END -----*/ // AGIPD::Data Members
// Device property data members
......@@ -107,6 +113,10 @@ public:
string uDPSrcMAC;
// IsMaster:
Tango::DevUShort isMaster;
// Microcontroller: the microcontroller used for monitoring the detectors
string microcontroller;
// ModuleIDInUc: the module id in micro controller.
Tango::DevUShort moduleIDInUc;
// Attribute data members
public:
......@@ -139,6 +149,8 @@ public:
Tango::DevString *attr_Mask_read;
Tango::DevString *attr_BunchStructureFile_read;
Tango::DevUShort *attr_TriggerMode_read;
Tango::DevULong *attr_FramesPerFile_read;
Tango::DevString *attr_MicroController_read;
Tango::DevShort *attr_LiveDataAnalog_read;
Tango::DevShort *attr_LiveDataDigital_read;
......@@ -168,7 +180,7 @@ public:
AGIPD(Tango::DeviceClass *cl,const char *s,const char *d);
/**
* The device object destructor.
*/
*/
~AGIPD() {delete_device();};
......@@ -504,6 +516,25 @@ public:
virtual void read_TriggerMode(Tango::Attribute &attr);
virtual void write_TriggerMode(Tango::WAttribute &attr);
virtual bool is_TriggerMode_allowed(Tango::AttReqType type);
/**
* Attribute FramesPerFile related methods
* Description: The frames stored in one nexus file.
*
* Data type: Tango::DevULong
* Attr type: Scalar
*/
virtual void read_FramesPerFile(Tango::Attribute &attr);
virtual void write_FramesPerFile(Tango::WAttribute &attr);
virtual bool is_FramesPerFile_allowed(Tango::AttReqType type);
/**
* Attribute MicroController related methods
* Description: display device name of microcontroller. It is not connected if device is not connected
*
* Data type: Tango::DevString
* Attr type: Scalar
*/
virtual void read_MicroController(Tango::Attribute &attr);
virtual bool is_MicroController_allowed(Tango::AttReqType type);
/**
* Attribute LiveDataAnalog related methods
* Description: live image data analog
......@@ -534,6 +565,7 @@ public:
// Command related methods
public:
/**
......@@ -585,8 +617,23 @@ public:
*/
virtual void load_bunch_structure();
virtual bool is_LoadBunchStructure_allowed(const CORBA::Any &any);
/**
* Command ConnectUc related method
* Description: manually connect to microcontroller
*
*/
virtual void connect_uc();
virtual bool is_ConnectUc_allowed(const CORBA::Any &any);
//--------------------------------------------------------
/**
* Method : AGIPD::add_dynamic_commands()
* Description : Add dynamic commands if any.
*/
//--------------------------------------------------------
void add_dynamic_commands();
/*----- PROTECTED REGION ID(AGIPD::Additional Method prototypes) ENABLED START -----*/
// Additional Method prototypes
......@@ -596,6 +643,7 @@ public:
string DevStringToString(Tango::DevString devstrData);
void UpdateFileName();
void RefreshDetector();
bool ConnectUC(string strUC);
/*----- PROTECTED REGION END -----*/ // AGIPD::Additional Method prototypes
};
......
<?xml version="1.0" encoding="ASCII"?>
<pogoDsl:PogoSystem xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pogoDsl="http://www.esrf.fr/tango/pogo/PogoDsl">
<classes name="AGIPD" pogoRevision="8.1">
<description description="AGIPD tango server" title="AGIPD" sourcePath="/home/yuelong/src/gitrepo/detsoftware/tango/agipd" language="Cpp" filestogenerate="XMI file,Code files,html Pages" hasMandatoryProperty="false" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false" descriptionHtmlExists="false">
<classes name="AGIPD" pogoRevision="9.4">
<description description="AGIPD tango server" title="AGIPD" sourcePath="/home/yuelong/src/gitrepo/detsoftware/tango/agipd" language="Cpp" filestogenerate="XMI file,Code files,Protected Regions,html Pages" hasMandatoryProperty="false" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false" descriptionHtmlExists="false">
<inheritances classname="Device_Impl" sourcePath=""/>
<identification contact="at desy.de - yuelong.yu" author="yuelong.yu" emailDomain="desy.de" classFamily="Acquisition" siteSpecific="" platform="Unix Like" bus="Ethernet" manufacturer="DESY(FS-DS)" reference=""/>
</description>
......@@ -55,6 +55,14 @@
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
<DefaultPropValue>0</DefaultPropValue>
</deviceProperties>
<deviceProperties name="Microcontroller" description="the microcontroller used for monitoring the detectors">
<type xsi:type="pogoDsl:StringType"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</deviceProperties>
<deviceProperties name="ModuleIDInUc" description="the module id in micro controller.">
<type xsi:type="pogoDsl:UShortType"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</deviceProperties>
<commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0">
<argin description="none">
<type xsi:type="pogoDsl:VoidType"/>
......@@ -125,6 +133,15 @@
</argout>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</commands>
<commands name="ConnectUc" description="manually connect to microcontroller" execMethod="connect_uc" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false">
<argin description="">
<type xsi:type="pogoDsl:VoidType"/>
</argin>
<argout description="">
<type xsi:type="pogoDsl:VoidType"/>
</argout>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</commands>
<attributes name="ADCLatency" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true">
<dataType xsi:type="pogoDsl:UShortType"/>
<changeEvent fire="false" libCheckCriteria="true"/>
......@@ -394,6 +411,22 @@
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
<properties description="trigger mode &#xA;0: internal trigger&#xA;1: external trigger" label="TriggerMode" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
</attributes>
<attributes name="FramesPerFile" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" memorizedAtInit="true" allocReadMember="true" isDynamic="false">
<dataType xsi:type="pogoDsl:UIntType"/>
<changeEvent fire="false" libCheckCriteria="false"/>
<archiveEvent fire="false" libCheckCriteria="false"/>
<dataReadyEvent fire="false" libCheckCriteria="true"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
<properties description="The frames stored in one nexus file." label="FramesPerFile" unit="" standardUnit="" displayUnit="" format="%6d" maxValue="" minValue="100" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
</attributes>
<attributes name="MicroController" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
<dataType xsi:type="pogoDsl:StringType"/>
<changeEvent fire="false" libCheckCriteria="false"/>
<archiveEvent fire="false" libCheckCriteria="false"/>
<dataReadyEvent fire="false" libCheckCriteria="true"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
<properties description="display device name of microcontroller. It is not connected if device is not connected" label="MicroController" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
</attributes>
<attributes name="LiveDataAnalog" attType="Image" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="1024" maxY="1024" allocReadMember="true">
<dataType xsi:type="pogoDsl:ShortType"/>
<changeEvent fire="false" libCheckCriteria="true"/>
......
......@@ -120,8 +120,8 @@ AGIPDClass *AGIPDClass::init(const char *name)
catch (bad_alloc &)
{
throw;
}
}
}
}
return _instance;
}
......@@ -237,6 +237,24 @@ CORBA::Any *LoadBunchStructureClass::execute(Tango::DeviceImpl *device, TANGO_UN
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : ConnectUcClass::execute()
* description : method to trigger the execution of the command.
*
* @param device The device on which the command must be executed
* @param in_any The command input data
*
* returns The command output data (packed in the Any object)
*/
//--------------------------------------------------------
CORBA::Any *ConnectUcClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{
cout2 << "ConnectUcClass::execute(): arrived" << endl;
((static_cast<AGIPD *>(device))->connect_uc());
return new CORBA::Any();
}
//===================================================================
// Properties management
......@@ -455,6 +473,32 @@ void AGIPDClass::set_default_property()
}
else
add_wiz_dev_prop(prop_name, prop_desc);
prop_name = "Microcontroller";
prop_desc = "the microcontroller used for monitoring the detectors";
prop_def = "";
vect_data.clear();
if (prop_def.length()>0)
{
Tango::DbDatum data(prop_name);
data << vect_data ;
dev_def_prop.push_back(data);
add_wiz_dev_prop(prop_name, prop_desc, prop_def);
}
else
add_wiz_dev_prop(prop_name, prop_desc);
prop_name = "ModuleIDInUc";
prop_desc = "the module id in micro controller.";
prop_def = "";
vect_data.clear();
if (prop_def.length()>0)
{
Tango::DbDatum data(prop_name);
data << vect_data ;
dev_def_prop.push_back(data);
add_wiz_dev_prop(prop_name, prop_desc, prop_def);
}
else
add_wiz_dev_prop(prop_name, prop_desc);
}
//--------------------------------------------------------
......@@ -487,104 +531,6 @@ void AGIPDClass::write_class_property()
description << str_desc;
data.push_back(description);
// put cvs or svn location
string filename("AGIPD");
filename += "Class.cpp";
// check for cvs information
string src_path(CvsPath);
start = src_path.find("/");
if (start!=string::npos)
{
end = src_path.find(filename);
if (end>start)
{
string strloc = src_path.substr(start, end-start);
// Check if specific repository
start = strloc.find("/cvsroot/");
if (start!=string::npos && start>0)
{
string repository = strloc.substr(0, start);
if (repository.find("/segfs/")!=string::npos)
strloc = "ESRF:" + strloc.substr(start, strloc.length()-start);
}
Tango::DbDatum cvs_loc("cvs_location");
cvs_loc << strloc;
data.push_back(cvs_loc);
}
}
// check for svn information
else
{
string src_path(SvnPath);
start = src_path.find("://");
if (start!=string::npos)
{
end = src_path.find(filename);
if (end>start)
{
header = "$HeadURL: ";
start = header.length();
string strloc = src_path.substr(start, (end-start));
Tango::DbDatum svn_loc("svn_location");
svn_loc << strloc;
data.push_back(svn_loc);
}
}
}
// Get CVS or SVN revision tag
// CVS tag
string tagname(TagName);
header = "$Name: ";
start = header.length();
string endstr(" $");
end = tagname.find(endstr);
if (end!=string::npos && end>start)
{
string strtag = tagname.substr(start, end-start);
Tango::DbDatum cvs_tag("cvs_tag");
cvs_tag << strtag;
data.push_back(cvs_tag);
}
// SVN tag
string svnpath(SvnPath);
header = "$HeadURL: ";
start = header.length();
end = svnpath.find(endstr);
if (end!=string::npos && end>start)
{
string strloc = svnpath.substr(start, end-start);
string tagstr ("/tags/");
start = strloc.find(tagstr);
if ( start!=string::npos )