API documentation
DelayAtomicSequence.cpp
Go to the documentation of this file.
00001 00005 /* 00006 * JEMRIS Copyright (C) 2007-2010 Tony Stöcker, Kaveh Vahedipour 00007 * Forschungszentrum Jülich, Germany 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 */ 00023 00024 #include "DelayAtomicSequence.h" 00025 #include "SequenceTree.h" 00026 #include "EmptyPulse.h" 00027 00028 /***********************************************************/ 00029 DelayAtomicSequence::DelayAtomicSequence (const DelayAtomicSequence& as) { 00030 00031 m_adc = 0; 00032 m_delay_time = 0.0; 00033 m_await_time = 0.0; 00034 m_phase_lock = false; 00035 m_delay_type = "B2E"; 00036 m_dt = DELAY_B2E; 00037 m_start = ""; 00038 m_stop = ""; 00039 m_mod_start = NULL; 00040 m_mod_stop = NULL; 00041 00042 }; 00043 00044 /***********************************************************/ 00045 bool DelayAtomicSequence::Prepare (PrepareMode mode) { 00046 00047 bool b=true; 00048 00049 ATTRIBUTE("Delay" , m_await_time); 00050 ATTRIBUTE("ADCs" , m_adc ); 00051 ATTRIBUTE("PhaseLock", m_phase_lock); 00052 ATTRIBUTE("StartSeq" , m_start ); 00053 ATTRIBUTE("StopSeq" , m_stop ); 00054 ATTRIBUTE("DelayType", m_delay_type); 00055 00056 //insert pulse and module-attributes for observation only once 00057 if (mode == PREP_INIT) { 00058 00059 //insert empty pulse 00060 if (GetNumberOfChildren()==0) 00061 b =InsertChild("EmptyPulse"); 00062 00063 //add attributes to link with durations of other modules 00064 for (int i=0;i<20;i++) { 00065 char modules[10]; 00066 sprintf( modules, "Module%02d", i ) ; 00067 HIDDEN_ATTRIBUTE(modules, m_durations[i] ); 00068 } 00069 } 00070 00071 //set delaytype for a quick later check in PREP_UPDATE 00072 if (mode != PREP_UPDATE) { 00073 if (m_delay_type == "B2E") m_dt = DELAY_B2E; 00074 if (m_delay_type == "C2E") m_dt = DELAY_C2E; 00075 if (m_delay_type == "B2C") m_dt = DELAY_B2C; 00076 if (m_delay_type == "C2C") m_dt = DELAY_C2C; 00077 } 00078 00079 b = ( SearchStartStopSeq() && b); 00080 double delay = GetDelay(mode); 00081 b = (delay >= 0.0 && b); 00082 00083 if (GetNumberOfChildren()>0) { 00084 ((Pulse*) GetChild(0))->SetNADC(m_adc); //pass my ADCs to the EmptyPulse 00085 ((Pulse*) GetChild(0))->SetPhaseLock(m_phase_lock); 00086 ((Pulse*) GetChild(0))->SetDuration(delay); 00087 if (mode != PREP_UPDATE) 00088 ((Pulse*) GetChild(0))->SetName("eP_"+GetName()); 00089 } 00090 00091 b = ( AtomicSequence::Prepare(mode) && b); 00092 00093 // Hide XML attributes which were set by AtomicSequence::Prepare() 00094 // delay atoms don't need a rot-matrix. 00095 if (mode != PREP_UPDATE) { 00096 HideAttribute("RotAngle",false); 00097 HideAttribute("Inclination",false); 00098 HideAttribute("Azimut",false); 00099 } 00100 00101 if (!b && mode == PREP_VERBOSE) 00102 cout << "Preparation of DelayAtomicSequence '" << GetName() << "' not succesful. Delay = " << delay << " ms" << endl; 00103 00104 return b; 00105 00106 } 00107 00108 /***********************************************************/ 00109 double DelayAtomicSequence::GetDelay(PrepareMode mode) { 00110 00111 double dDelayTime = m_await_time; 00112 00113 //if (m_mod_start==NULL && m_mod_stop==NULL) return dDelayTime; 00114 00115 Module* pMod = GetParent(); 00116 if (pMod == NULL) return -1.0; 00117 00118 //find other sequences between pModStart, myself, and pModStop 00119 int iMYpos=0, iS1pos=10000, iS2pos=-1; 00120 for (int i=0;i<pMod->GetNumberOfChildren();++i) { 00121 if( this == pMod->GetChild(i)) iMYpos=i; 00122 if(m_mod_start == pMod->GetChild(i)) iS1pos=i; 00123 if(m_mod_stop == pMod->GetChild(i)) iS2pos=i; 00124 } 00125 iS1pos = (iMYpos<iS1pos)?iMYpos:iS1pos; 00126 iS2pos = (iMYpos>iS2pos)?iMYpos:iS2pos; 00127 00128 //Observe these sequences 00129 int j = 0; 00130 for (int i=iS1pos;i<=iS2pos;++i) 00131 if (i!=iMYpos && mode == PREP_VERBOSE) { 00132 char modules[10]; 00133 sprintf( modules, "Module%02d", j ) ; 00134 Observe( GetAttribute(modules), pMod->GetChild(i)->GetName(),"Duration", mode == PREP_VERBOSE ); 00135 j++; 00136 } 00137 00138 //subtract duration of other sequences between pModStart, myself, and pModStop 00139 //do this twice, since cross-dependencies may hinder success in first attempt 00140 for (int j=0;j<2;j++) { 00141 dDelayTime = m_await_time; 00142 for (int i=iS1pos;i<=iS2pos;++i) { 00143 double dfact = ( ( i==iS2pos && (m_dt==DELAY_B2C || m_dt==DELAY_C2C) ) || 00144 ( i==iS1pos && (m_dt==DELAY_C2E || m_dt==DELAY_C2C) ) )?0.5:1.0; 00145 if (i!=iMYpos) 00146 dDelayTime -= dfact * pMod->GetChild(i)->GetDuration(); 00147 00148 } 00149 } 00150 00151 00152 #ifdef DEBUG 00153 cout << " DELAYTOMICSEQUENCE: " << GetName() << " mode = " << mode << " , m_await_time = " << m_await_time 00154 << " , (iS1pos, iMYpos, iS2pos) = (" << iS1pos << "," << iMYpos << "," << iS2pos << ")" 00155 << " => delay = " << dDelayTime << endl; 00156 #endif 00157 00158 00159 return dDelayTime; 00160 00161 } 00162 00163 /***********************************************************/ 00164 bool DelayAtomicSequence::SearchStartStopSeq () { 00165 00166 m_mod_start = NULL; 00167 m_mod_stop = NULL; 00168 00169 Module* pMod = GetParent(); 00170 if (pMod == NULL) return false; 00171 00172 int i1=0, i2=pMod->GetNumberOfChildren(); 00173 for (int i=0;i<pMod->GetNumberOfChildren();++i) { 00174 if( m_start == pMod->GetChild(i)->GetName() ) { m_mod_start = pMod->GetChild(i); i1=i; } 00175 if( m_stop == pMod->GetChild(i)->GetName() ) { m_mod_stop = pMod->GetChild(i); i2=i; } 00176 } 00177 00178 return (i1<i2); 00179 00180 } 00181 00182 /***********************************************************/ 00183 string DelayAtomicSequence::GetInfo () { 00184 00185 string ret; 00186 00187 switch (m_dt) { 00188 case DELAY_B2E : ret=" DelayType = B2E "; break; 00189 case DELAY_C2C : ret=" DelayType = C2C "; break; 00190 case DELAY_B2C : ret=" DelayType = B2C "; break; 00191 case DELAY_C2E : ret=" DelayType = C2E "; break; 00192 default: ret=" unkown DelayType "; 00193 } 00194 00195 if (!m_start.empty()) ret = ret+" , StartSeq = "+m_start; 00196 if (!m_stop.empty() ) ret = ret+" , StopSeq = "+m_stop; 00197 00198 return ret; 00199 00200 }; 00201
