33 namespace RestFrames {
36 const std::string& stitle,
37 int Ncomb,
int Nobject)
38 :
Jigsaw(sname, stitle, Ncomb, Nobject),
39 m_Ncomb(Ncomb), m_Nobj(Nobject)
41 m_Type = kCombinatoricJigsaw;
42 for(
int i = 0; i < m_Ncomb; i++){
43 m_ChildStates += GetNewChildState();
45 m_SetTransverse =
false;
49 :
Jigsaw(), m_Ncomb(0), m_Nobj(0) {}
51 CombinatoricJigsaw::~CombinatoricJigsaw() {}
74 void CombinatoricJigsaw::SetParentState(
State& state){
77 Jigsaw::SetParentState(state);
80 CombinatoricState
const& CombinatoricJigsaw::GetParentState()
const {
81 if(!Jigsaw::GetParentState())
84 return static_cast<const CombinatoricState&
>(Jigsaw::GetParentState());
87 CombinatoricState& CombinatoricJigsaw::GetChildState(
int i)
const {
88 if(!Jigsaw::GetChildState(i))
91 return static_cast<CombinatoricState&
>(Jigsaw::GetChildState(i));
99 int N = frames.GetN();
100 for(
int f = 0; f < N; f++)
101 AddChildFrame(frames[f], i);
105 int N = frames.GetN();
106 for(
int f = 0; f < N; f++)
116 int N = frames.GetN();
117 for(
int f = 0; f < N; f++)
118 AddDependancyFrame(frames[f], i);
122 int N = frames.GetN();
123 for(
int f = 0; f < N; f++)
128 if(i < 0 || i >= m_Ncomb)
131 m_ChargeForChild[i] = charge;
143 if(m_ChargeForChild.count(i) > 0)
144 m_ChargeForChild.erase(i);
148 if(i < 0 || i >= m_Nobj)
151 m_ChargeForObject[i] = charge;
163 if(m_ChargeForObject.count(i) > 0)
164 m_ChargeForObject.erase(i);
167 bool CombinatoricJigsaw::InitializeJigsawExecutionList(
JigsawList& exec_jigsaws,
JigsawList& todo_jigsaws){
168 if(!IsSoundMind())
return false;
169 if(exec_jigsaws.Contains(*
this))
return true;
171 m_ExecuteJigsaws.Clear();
175 FillGroupJigsawDependancies(group_jigsaws);
176 group_jigsaws -= *
this;
178 int Ngroup = group_jigsaws.GetN();
179 for(
int i = Ngroup-1; i >= 0; i--){
180 Jigsaw& jigsaw = group_jigsaws[i];
181 if(!exec_jigsaws.Contains(jigsaw))
182 if(!jigsaw.InitializeJigsawExecutionList(exec_jigsaws, todo_jigsaws))
183 return SetMind(
false);
184 m_DependancyJigsaws -= jigsaw;
188 while(m_DependancyJigsaws.GetN() > 0){
189 Jigsaw& jigsaw = m_DependancyJigsaws[m_DependancyJigsaws.GetN()-1];
190 if(exec_jigsaws.Contains(jigsaw)){
191 m_DependancyJigsaws -= jigsaw;
194 if(!jigsaw.DependsOnJigsaw(*
this)){
195 if(!jigsaw.InitializeJigsawExecutionList(exec_jigsaws, todo_jigsaws)){
196 return SetMind(
false);
198 m_DependancyJigsaws -= jigsaw;
202 JigsawList temp_todo_jigsaws = todo_jigsaws;
203 exec_jigsaws += *
this;
204 exec_jigsaws += m_ExecuteJigsaws;
205 m_DependancyJigsaws -= jigsaw;
206 if(!jigsaw.InitializeJigsawExecutionList(exec_jigsaws, temp_todo_jigsaws))
207 return SetMind(
false);
208 temp_todo_jigsaws -= todo_jigsaws;
209 exec_jigsaws -= *
this;
210 m_DependancyJigsaws -= exec_jigsaws;
211 m_ExecuteJigsaws += temp_todo_jigsaws;
214 exec_jigsaws += *
this;
215 todo_jigsaws += *
this;
220 CombinatoricState& CombinatoricJigsaw::GetNewChildState(){
222 sprintf(strn,
"%d",GetNChildren());
223 std::string name =
GetName()+
"_"+std::string(strn);
224 CombinatoricState* statePtr =
new CombinatoricState(name, name);
229 bool CombinatoricJigsaw::ExecuteDependancyJigsaws(){
230 int N = m_ExecuteJigsaws.GetN();
231 for(
int i = 0; i < N; i++){
232 if(!m_ExecuteJigsaws[i].AnalyzeEvent())
238 bool CombinatoricJigsaw::AnalyzeEvent(){
240 return SetSpirit(
false);
242 if(!InitializeCombinatoric()){
244 m_Log <<
"Problem initializing event info" << LogEnd;
245 return SetSpirit(
false);
248 if(!LoopCombinatoric()){
250 m_Log <<
"Problem looping over combinatorics" << LogEnd;
251 return SetSpirit(
false);
254 return SetSpirit(
true);
257 bool CombinatoricJigsaw::InitializeAnalysis(){
258 if(!Jigsaw::InitializeAnalysis())
259 return SetMind(
false);
261 CombinatoricGroup& group =
GetGroup();
264 m_NExclusive.clear();
267 m_NExclusiveTOT =
true;
269 for(
int i = 0; i < m_Ncomb; i++){
270 RestFrameList
const& frames = GetChildState(i).
GetListFrames();
271 int Nf = frames.GetN();
274 for(
int f = 0; f < Nf; f++){
277 group.GetNElementsForFrame(frames[f], N, excl);
278 if(N < 0)
return SetMind(
false);
280 exclTOT = exclTOT && excl;
282 m_NForChild.push_back(NTOT);
283 m_NExclusive.push_back(exclTOT);
285 m_NExclusiveTOT = m_NExclusiveTOT && exclTOT;
288 return SetMind(
true);
291 bool CombinatoricJigsaw::InitializeCombinatoric(){
293 return SetSpirit(
false);
296 return SetSpirit(
false);
298 if(!GetParentState())
299 return SetSpirit(
false);
301 m_InputStates.Clear();
304 if(m_InputStates.GetN() < m_NinputTOT){
306 m_Log <<
"Unable to execute Jigsaw. ";
307 m_Log <<
"Insufficienct number of inputs: ";
308 m_Log << m_NinputTOT <<
" (required) != ";
309 m_Log << m_InputStates.GetN() <<
" (provided)";
311 return SetSpirit(
false);
314 if(m_NExclusiveTOT &&
315 (m_InputStates.GetN() != m_NinputTOT)){
317 m_Log <<
"Unable to execute Jigsaw. ";
318 m_Log <<
"Incorrect number of exclusive inputs: ";
319 m_Log << m_NinputTOT <<
" (required) != ";
320 m_Log << m_InputStates.GetN() <<
" (provided)";
322 return SetSpirit(
false);
325 return SetSpirit(
true);
329 m_SetTransverse = tran;
331 m_TranAxis = axis.Unit();
334 bool CombinatoricJigsaw::IsTransverse()
const {
335 return m_SetTransverse;
338 const TVector3& CombinatoricJigsaw::GetTransverseAxis()
const {
342 int CombinatoricJigsaw::GetNInputStates()
const {
343 return m_InputStates.GetN();
346 VisibleState& CombinatoricJigsaw::GetInputState(
int i)
const {
347 return m_InputStates[i];
350 int CombinatoricJigsaw::GetNinputForChild(
int i)
const {
351 if(i < 0 || i >= m_Ncomb)
353 return m_NForChild[i];
356 bool CombinatoricJigsaw::IsNinputExclForChild(
int i)
const {
357 if(i < 0 || i >= m_Ncomb)
359 return m_NExclusive[i];
362 bool CombinatoricJigsaw::IsChargeSetForChild(
int i)
const {
363 return !(m_ChargeForChild.count(i) == 0);
366 RFCharge CombinatoricJigsaw::GetChargeForChild(
int i)
const {
367 if(IsChargeSetForChild(i))
368 return m_ChargeForChild[i];
373 bool CombinatoricJigsaw::IsChargeSetForObject(
int i)
const {
374 return !(m_ChargeForObject.count(i) == 0);
377 RFCharge CombinatoricJigsaw::GetChargeForObject(
int i)
const {
378 if(IsChargeSetForObject(i))
379 return m_ChargeForObject[i];
384 bool CombinatoricJigsaw::LoopCombinatoric(){
385 int Ninput = m_InputStates.GetN();
388 for(
int i = 0; i < Ninput; i++) N_comb *= m_Ncomb;
391 double metric_min = -1;
393 for(
int c = 0; c < N_comb; c++){
395 for(
int i = 0; i < m_Ncomb; i++)
399 for(
int i = 0; i < Ninput; i++){
400 int ihem = key%m_Ncomb;
402 GetChildState(ihem).
AddElement(m_InputStates[i]);
407 for(
int i = 0; i < m_Ncomb; i++){
408 if(IsNinputExclForChild(i)){
409 if(GetChildState(i).GetNElements() != GetNinputForChild(i)){
414 if(GetChildState(i).GetNElements() < GetNinputForChild(i)){
419 if(IsChargeSetForChild(i)){
420 if(GetChildState(i).GetCharge() != GetChargeForChild(i)){
430 if(!ExecuteDependancyJigsaws())
434 for(
int i = 0; i < m_Nobj; i++){
435 if(IsChargeSetForObject(i)){
436 if(GetDependancyStates(i).GetCharge() != GetChargeForObject(i)){
447 if(!EvaluateMetric(metric))
450 if(metric < metric_min || c_min < 0){
455 if((metric < metric_min && metric >= 0.) || c_min < 0){
463 m_Log <<
"Unable to find combinatoric satisfying ";
464 m_Log <<
"requested conditions." << LogEnd;
465 return SetSpirit(
false);
469 for(
int i = 0; i < m_Ncomb; i++)
472 for(
int i = 0; i < Ninput; i++){
473 int ihem = key%m_Ncomb;
475 GetChildState(ihem).
AddElement(m_InputStates[i]);
479 if(!ExecuteDependancyJigsaws())
480 return SetSpirit(
false);
482 return SetSpirit(
true);
485 bool CombinatoricJigsaw::IsSoundBody()
const {
486 if(RFBase::IsSoundBody())
489 if(!Jigsaw::IsSoundBody())
490 return SetBody(
false);
492 for(
int i = 0; i < m_Nobj; i++){
495 m_Log <<
"Empty collection of object frames: " << i;
497 return SetBody(
false);
501 return SetBody(
true);