SoftOpExternalMgr.cpp 9.62 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################
22
23
24
#include "SoftOpExternalMgr.h"
using namespace lima;

seb's avatar
seb committed
25
static SoftOpKey SoftOpTable[] = {
26
  SoftOpKey(BACKGROUNDSUBSTRACTION,"Background substraction"),
27
28
29
30
31
  SoftOpKey(BINNING,"Binning"),
  SoftOpKey(BPM,"Bpm"),
  SoftOpKey(FLATFIELDCORRECTION,"Flat field correction"),
  SoftOpKey(FLIP,"Flip"),
  SoftOpKey(MASK,"Mask"),
32
  SoftOpKey(ROICOUNTERS,"Roi counters"),
33
  SoftOpKey(ROI2SPECTRUM,"Roi 2 spectrum"),
34
  SoftOpKey(SOFTROI,"Software roi"),
35
36
  SoftOpKey(USER_LINK_TASK,"User link task"),
  SoftOpKey(USER_SINK_TASK,"User sink task"),
37
  SoftOpKey()
seb's avatar
seb committed
38
39
};

40
static SoftOpKey getSoftOpKey(SoftOpId anId)
41
{
42
43
44
45
46
47
  for(unsigned int i = 0;i < sizeof(SoftOpTable);++i)
    {
      if(SoftOpTable[i].m_id == anId)
	return SoftOpTable[i];
    }
  return SoftOpKey();
48
49
}

50
51
52
SoftOpExternalMgr::SoftOpExternalMgr() :
  m_end_link_callback(NULL),
  m_end_sink_callback(NULL)
53
54
55
{
}

56
SoftOpExternalMgr::~SoftOpExternalMgr()
57
{
58
59
60
61
62
63
64
65
66
67
  if(m_end_link_callback)
    m_end_link_callback->unref();
  if(m_end_sink_callback)
    m_end_sink_callback->unref();

  for(Stage2Instance::iterator i = m_stage2instance.begin();
      i != m_stage2instance.end();++i)
    for(std::list<SoftOpInstance>::iterator k = i->second.begin();
	k != i->second.end();k = i->second.erase(k))
      delete k->m_opt;
68
69
}

70
void SoftOpExternalMgr::getAvailableOp(const SoftOpKey* &available) const
71
{
72
  available = SoftOpTable;
73
74
}

75
void SoftOpExternalMgr::getActiveOp(std::map<stage,std::list<alias> > &activeOp) const
76
{
77
  AutoMutex aLock(m_cond.mutex());
78
79
80
81
82
83
84
85
86
87
88
  for(Stage2Instance::const_iterator i = m_stage2instance.begin();
      i != m_stage2instance.end();++i)
    {
      std::pair<std::map<stage,std::list<alias> >::iterator,bool> result =
	activeOp.insert(std::pair<stage,std::list<alias> >(i->first,std::list<alias>()));
      std::list<alias> &aliasList = result.first->second;

      for(std::list<SoftOpInstance>::const_iterator k = i->second.begin();
	  k != i->second.end();++k)
	aliasList.push_back(k->m_alias);
    }
89
90
}

91
void SoftOpExternalMgr::getActiveStageOp(stage aStage,std::list<alias> &activeOp) const
92
{
93
  AutoMutex aLock(m_cond.mutex());
94
95
96
97
98
  Stage2Instance::const_iterator i = m_stage2instance.find(aStage);
  if(i != m_stage2instance.end())
    for(std::list<SoftOpInstance>::const_iterator k = i->second.begin();
	  k != i->second.end();++k)
      activeOp.push_back(k->m_alias);
99
100
}

101
void SoftOpExternalMgr::addOp(SoftOpId aSoftOpId,
102
103
			      const alias &anAlias,int aStage,
			      SoftOpInstance &anInstance)
104
{
105
106
107
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR3(aSoftOpId,anAlias,aStage);

108
  AutoMutex aLock(m_cond.mutex());
109
110
  _checkIfPossible(aSoftOpId,aStage);
  SoftOpInstance newInstance(getSoftOpKey(aSoftOpId),anAlias);
111
  
112
113
114
115
116
  switch(aSoftOpId)
    {
    case ROICOUNTERS:
      newInstance.m_opt = new SoftOpRoiCounter();
      break;
117
118
    case BPM:
      newInstance.m_opt = new SoftOpBpm();
119
      break;
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    case BACKGROUNDSUBSTRACTION:
      newInstance.m_opt = new SoftOpBackgroundSubstraction();
      newInstance.m_linkable = true;
      break;
    case BINNING:
      newInstance.m_opt = new SoftOpBinning();
      newInstance.m_linkable = true;
      break;
    case FLATFIELDCORRECTION:
      newInstance.m_opt = new SoftOpFlatfieldCorrection();
      newInstance.m_linkable = true;
      break;
    case FLIP:
      newInstance.m_opt = new SoftOpFlip();
      newInstance.m_linkable = true;
      break;
    case MASK:
      newInstance.m_opt = new SoftOpMask();
      newInstance.m_linkable = true;
      break;
140
141
142
    case ROI2SPECTRUM:
      newInstance.m_opt = new SoftOpRoi2Spectrum();
      break;
143
144
145
146
    case SOFTROI:
      newInstance.m_opt = new SoftOpSoftRoi();
      newInstance.m_linkable = true;
      break;
147
148
149
150
151
152
153
    case USER_LINK_TASK:
      newInstance.m_opt = new SoftUserLinkTask();
      newInstance.m_linkable = true;
      break;
    case USER_SINK_TASK:
      newInstance.m_opt = new SoftUserSinkTask();
      break;
154
    default:
155
      THROW_CTL_ERROR(InvalidValue) << "Not yet managed";
156
157
158
159
    }
  std::pair<Stage2Instance::iterator,bool> aResult = 
    m_stage2instance.insert(std::pair<stage,std::list<SoftOpInstance> >(aStage,std::list<SoftOpInstance>()));
  aResult.first->second.push_back(newInstance);
160
  anInstance = newInstance;
161
162
}

163
void SoftOpExternalMgr::delOp(const alias &anAlias)
164
{
165
   AutoMutex aLock(m_cond.mutex());
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
   for(Stage2Instance::iterator i = m_stage2instance.begin();
      i != m_stage2instance.end();++i)
    {
      for(std::list<SoftOpInstance>::iterator k = i->second.begin();
	  k != i->second.end();++k)
	{
	  if(k->m_alias == anAlias)
	    {
	      delete k->m_opt;
	      i->second.erase(k);
	      if(i->second.empty())
		m_stage2instance.erase(i);
	      return;
	    }
	}
    }
182
183
}

184
185
void SoftOpExternalMgr::getOpClass(const alias &anAlias,
				   SoftOpInstance &aSoftOpInstance) const
186
{
187
  AutoMutex aLock(m_cond.mutex());
188
189
190
191
192
193
194
195
196
197
198
199
200
  for(Stage2Instance::const_iterator i = m_stage2instance.begin();
      i != m_stage2instance.end();++i)
    {
      for(std::list<SoftOpInstance>::const_iterator k = i->second.begin();
	  k != i->second.end();++k)
	{
	  if(k->m_alias == anAlias)
	    {
	      aSoftOpInstance = *k;
	      return;
	    }
	}
    }
201
}
seb's avatar
seb committed
202
203
204

void SoftOpExternalMgr::setEndLinkTaskCallback(TaskEventCallback *aCbk)
{
205
206
207
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(aCbk);

208
209
210
211
212
  if(m_end_link_callback)
    m_end_link_callback->unref();
  m_end_link_callback = aCbk;
  if(m_end_link_callback)
    m_end_link_callback->ref();
seb's avatar
seb committed
213
214
}

215
void SoftOpExternalMgr::setEndSinkTaskCallback(TaskEventCallback *aCbk)
seb's avatar
seb committed
216
{
217
218
219
220
221
  if(m_end_sink_callback)
    m_end_sink_callback->unref();
  m_end_sink_callback = aCbk;
  if(m_end_sink_callback)
    m_end_sink_callback->ref();
seb's avatar
seb committed
222
223
}

224
void SoftOpExternalMgr::addTo(TaskMgr &aTaskMgr,
seb's avatar
seb committed
225
226
227
			      int begin_stage,
			      int &last_link_task,int &last_sink_task)
{
228
229
230
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(begin_stage);

231
  AutoMutex aLock(m_cond.mutex());
232
  last_link_task = last_sink_task = -1;
seb's avatar
seb committed
233
  int nextStage = begin_stage;
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
  for(Stage2Instance::iterator i = m_stage2instance.begin();
      i != m_stage2instance.end();++i,++nextStage)
    {
      for(std::list<SoftOpInstance>::const_iterator k = i->second.begin();
	  k != i->second.end();++k)
	{
	  if(k->m_linkable)
	    last_link_task = nextStage;
	  else
	    last_sink_task = nextStage;
	  k->m_opt->addTo(aTaskMgr,nextStage);
	}
    }
  std::pair<int,LinkTask*> aLastLink(0,NULL);
  std::pair<int,SinkTaskBase*> aLastSink(0,NULL);

  aTaskMgr.getLastTask(aLastLink,aLastSink);

252
  if(aLastLink.first >= begin_stage)
253
    aLastLink.second->setEventCallback(m_end_link_callback);
254
  if(aLastSink.first >= begin_stage)
seb's avatar
seb committed
255
256
257
258
259
260
    {
      SinkTaskBase *aDummyPt = new SinkTaskBase();
      aDummyPt->setEventCallback(m_end_sink_callback);
      aTaskMgr.addSinkTask(aLastSink.first + 1,aDummyPt);
      aDummyPt->unref();
    }
261
  DEB_RETURN() << DEB_VAR2(last_link_task,last_sink_task);
262
263
264
265
266
}

void SoftOpExternalMgr::_checkIfPossible(SoftOpId aSoftOpId,
					 int stage)
{
267
268
269
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR2(aSoftOpId,stage);

270
271
272
273
274
  bool checkLinkable = false;
  switch(aSoftOpId) 
    {
    case ROICOUNTERS:
    case BPM:
275
    case USER_SINK_TASK:
276
    case ROI2SPECTRUM:
277
      break;			// always possible
278
279
280
281
282
283
    case BACKGROUNDSUBSTRACTION:
    case BINNING:
    case FLATFIELDCORRECTION:
    case FLIP:
    case MASK:
    case SOFTROI:
284
    case USER_LINK_TASK:
285
286
      checkLinkable = true;
      break;
287
    default:
288
      THROW_CTL_ERROR(InvalidValue) << "Not yet managed";
289
290
    }

291
292
  DEB_TRACE() << DEB_VAR1(checkLinkable);

293
294
  if(checkLinkable)
    {
295
296
297
298
299
300
301
302
303
304
305
      Stage2Instance::iterator i = m_stage2instance.find(stage);
      if(i != m_stage2instance.end())
	{
	  for(std::list<SoftOpInstance>::iterator k = i->second.begin();
	      k != i->second.end();++k)
	    {
	      if(k->m_linkable)
		{
		  char buffer[256];
		  snprintf(buffer,sizeof(buffer),"%s task  %s is already active on that level",
			   k->m_key.m_name,k->m_alias.c_str());
306
		  THROW_CTL_ERROR(Error) << buffer;
307
308
309
		}
	    }
	}
310
311
312
313
314
    }
}

void SoftOpExternalMgr::isTaskActive(bool &linkTaskFlag,bool &sinkTaskFlag) const
{
315
  DEB_MEMBER_FUNCT();
316
317

  AutoMutex aLock(m_cond.mutex());
318
319
320
321
322
323
324
325
326
327
328
329
330
  linkTaskFlag = sinkTaskFlag = false;
  for(Stage2Instance::const_iterator i = m_stage2instance.begin();
      i != m_stage2instance.end() && (!linkTaskFlag || !sinkTaskFlag);++i)
    {
      for(std::list<SoftOpInstance>::const_iterator k = i->second.begin();
	  k != i->second.end() && (!linkTaskFlag || !sinkTaskFlag);++k)
	{
	 if(k->m_linkable)
	    linkTaskFlag = true;
	  else
	    sinkTaskFlag = true;
	}
    }
331
  DEB_RETURN() << DEB_VAR2(linkTaskFlag,sinkTaskFlag);
332
333
334
335
336
}


void SoftOpExternalMgr::prepare()
{
337
  AutoMutex aLock(m_cond.mutex());
338
339
340
341
342
  for(Stage2Instance::iterator i = m_stage2instance.begin();
      i != m_stage2instance.end();++i)
    for(std::list<SoftOpInstance>::iterator k = i->second.begin();
	k != i->second.end();++k)
      k->m_opt->prepare();
seb's avatar
seb committed
343
}