Thanks for all you guys inputs.<br><br>The v3 and v4 code base are both from ITK 4.2.0.  The two version code I created both used 8 threads.<br><br>I do found that the v3 version code used smaller number of sample points. So I changed the v3 code (as attached at the bottom) to use the same amount of points as those of the v4 counterpart (ie., 10% of total amount of voxels) at different resolution levels.  I did this through the observer with something like:<br>
        if (vRegistration-&gt;GetCurrentLevel() == 0)<br>        {<br>            Metric-&gt;SetNumberOfSpatialSamples(18176);<br>        } else if (vRegistration-&gt;GetCurrentLevel() == 1)<br>        {<br>            Metric-&gt;SetNumberOfSpatialSamples( 151815 );<br>
        } else<br>        {<br>            Metric-&gt;SetNumberOfSpatialSamples( 1223322 );<br>        }<br><br>To my eyes, everything looks similar (but, like I said, I am just a newbie and not so sure about my judgement). I ran this changed v3 code, and it took about 45 s.  It is about half of the v4 code, which is around 90 s as reported yesterday.<br>
<br>As for plotting the convergence curve, I am not so familiar of how to use it (probably I would go over the ItkSoftwareGuide again). Seems to me, multiple curves should be plotted with the 6 parameter transform. But, anyway, I am going to try some plots.<br>
<br>BTW, the matching performance of the v4 code is a little bit better than that of the v3 code (ie., DiceValue(v4-code) = 0.821 vs. DiceValue(v3-code) = 0.803). But, I am not sure, since this is just on one data. However, I am hoping that the automatically estimated learning rate and parameter scaling in v4 would help. <br>
<br><br><br>//=== Start of v3 code ============================================<br>//<br><br>void RigidTransform(AffineType::Pointer vAffine, ImageType const&amp; vFixImage, <br>    ImageType const&amp; vMovImage)<br>{<br>
    //- Rotation center<br>    typedef itk::Euler3DTransform&lt;double&gt; RigidType;<br>    RigidType::Pointer vRigid = RigidType::New();<br>    typedef itk::CenteredTransformInitializer&lt;RigidType,<br>                                                ImageType, <br>
                                                ImageType &gt;    InitializerType;<br>    InitializerType::Pointer Initializer = InitializerType::New();<br>    Initializer-&gt;SetTransform(   vRigid );<br>    Initializer-&gt;SetFixedImage(  &amp;vFixImage );<br>
    Initializer-&gt;SetMovingImage( &amp;vMovImage );<br>    Initializer-&gt;GeometryOn();<br>    Initializer-&gt;InitializeTransform();<br><br>    //- Rigid registration<br>    // ...<br>    typedef itk::LinearInterpolateImageFunction&lt;<br>
                                    ImageType,<br>                                    double          &gt;        InterpolatorType;<br>    typedef itk::GradientDescentOptimizer            RigidOptimizerType;<br><br>    //- Instantiate major objects.<br>
    RigidOptimizerType::Pointer Optimizer      = RigidOptimizerType::New();<br>    InterpolatorType::Pointer   Interpolator  = InterpolatorType::New();<br>    RegistrationType::Pointer   Registration  = RegistrationType::New();<br>
<br>    Registration-&gt;SetNumberOfLevels(3);<br><br>    //- Assemble to the registration pipeline<br>    Registration-&gt;SetOptimizer(     Optimizer     );<br>    Registration-&gt;SetInterpolator(  Interpolator  );<br>
    Registration-&gt;SetFixedImage(  &amp;vFixImage   );<br>    Registration-&gt;SetMovingImage( &amp;vMovImage   );<br>    ImageType::RegionType FixRegion = vFixImage.GetBufferedRegion();<br>    Registration-&gt;SetFixedImageRegion( FixRegion );<br>
    Registration-&gt;SetInitialTransformParameters( vRigid-&gt;GetParameters() );<br>    Registration-&gt;SetTransform( vRigid );<br><br>    //- Optimizer<br>    typedef RigidOptimizerType::ScalesType       OptimizerScalesType;<br>
    OptimizerScalesType vOptimizerScales( vRigid-&gt;GetNumberOfParameters() );<br>    const double vTranslationScale = 1.0 / 1000;<br>    vOptimizerScales[0] = 1.0;<br>    vOptimizerScales[1] = 1.0;<br>    vOptimizerScales[2] = 1.0;<br>
    vOptimizerScales[3] = vTranslationScale;<br>    vOptimizerScales[4] = vTranslationScale;<br>    vOptimizerScales[5] = vTranslationScale;<br>    Optimizer-&gt;SetScales( vOptimizerScales );<br>    Optimizer-&gt;SetNumberOfIterations(50);<br>
    Optimizer-&gt;SetLearningRate(0.3);<br>    RigidOptimizerType::ParametersType vParameters = vRigid-&gt;GetParameters();<br>    Optimizer-&gt;SetInitialPosition(vParameters);<br><br>    //- Metric<br>    //<br>    typedef itk::MattesMutualInformationImageToImageMetric&lt;<br>
                                        ImageType,<br>                                        ImageType &gt;                MetricType;<br>    MetricType::Pointer Metric = MetricType::New();<br>    vRegistration-&gt;SetMetric(Metric);<br>
    Metric-&gt;SetNumberOfHistogramBins(32);<br>    Metric-&gt;ReinitializeSeed( 76926294 );<br><br>    //- Setup observers<br>    //<br>    RigidRegistrationInterfaceCommand::Pointer vInterface = RigidRegistrationInterfaceCommand::New();<br>
    Registration-&gt;AddObserver(itk::IterationEvent(), vInterface);<br>    OptimizerObserver::Pointer vOptimizerObserver = OptimizerObserver::New();<br>    vOptimizerObserver-&gt;mRigidMetric = dynamic_cast&lt;itk::MattesMutualInformationImageToImageMetric&lt;ImageType, ImageType&gt;*&gt;<br>
        (Registration-&gt;GetMetric());<br>    Optimizer-&gt;AddObserver(itk::StartEvent(), vOptimizerObserver);<br>    Optimizer-&gt;AddObserver(itk::IterationEvent(), vOptimizerObserver);<br><br>    //- Do Translation Registration<br>
    try<br>    {<br>        Registration-&gt;Update();<br>    }<br>    catch( itk::ExceptionObject &amp; err )<br>    {<br>        std::cerr &lt;&lt; &quot;ExceptionObject caught !&quot; &lt;&lt; std::endl;<br>        std::cerr &lt;&lt; err &lt;&lt; std::endl;<br>
    }<br>    std::cout &lt;&lt; &quot;Rigid Registration completed&quot; &lt;&lt; std::endl;<br>    std::cout &lt;&lt; std::endl;<br><br>    vRigid-&gt;SetParameters(Registration-&gt;GetLastTransformParameters());<br><br>
}<br><br>//<br>//=== End of v3 code =============================================<br><br><br><div class="gmail_quote">2012/10/26 brian avants <span dir="ltr">&lt;<a href="mailto:stnava@gmail.com" target="_blank">stnava@gmail.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">just to be a bit clearer ---- there are several key points in a<br>
reasonable comparison:<br>
<br>
1.  how many threads are you using?<br>
<br>
2.  how many points are you using to sample the mutual information?<br>
<br>
3.  what is the shape of the convergence curve showing the mutual information?<br>
<br>
4.  what version of v4 are you using?<br>
<br>
point 2 is probably the most critical.<br>
<br>
for instance, the v4 registration methods have the option<br>
<br>
registration-&gt;SetMetricSamplingPercentage(0.1);<br>
<br>
which ( with the above setting ) will sample 10% of your image -----<br>
at each resolution.<br>
<br>
this is very different than v3 which , in general , uses a fixed<br>
number of samples.<br>
<br>
v4 supports that strategy too but it is not the default.<br>
<br>
so, in comparison, you may have set up your v3 metric with something like<br>
<br>
metric-&gt;SetNumberOfSamples(   20000  )<br>
<br>
which would only be about  0.1 % of the image points.<br>
<br>
so you might first try doing<br>
<br>
registration-&gt;SetMetricSamplingPercentage(0.01);<br>
<br>
to see how this affects speed.<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
brian<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<br>
On Fri, Oct 26, 2012 at 9:12 AM, lien lee &lt;<a href="mailto:lienlee@gmail.com">lienlee@gmail.com</a>&gt; wrote:<br>
&gt; Thanks for the informative reply, Brian. I am going to double check, and<br>
&gt; will let you know what I could get.<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; 2012/10/25 brian avants &lt;<a href="mailto:stnava@gmail.com">stnava@gmail.com</a>&gt;<br>
&gt;&gt;<br>
&gt;&gt; hi lien<br>
&gt;&gt;<br>
&gt;&gt; thanks for trying out v4.<br>
&gt;&gt;<br>
&gt;&gt; i would not give up on it yet as there are many ways to use the v4<br>
&gt;&gt; framework.<br>
&gt;&gt;<br>
&gt;&gt; i don&#39;t know off hand which is the most computationally efficient<br>
&gt;&gt; approach --- to some extent we rely on users to help us understand<br>
&gt;&gt; these questions as the number of active developers, right now, is<br>
&gt;&gt; relatively few.<br>
&gt;&gt;<br>
&gt;&gt; typically, if we have questions about efficiency , we use a profiler<br>
&gt;&gt; to help understand sources of additional computation.<br>
&gt;&gt;<br>
&gt;&gt; michael stauffer has done the majority of profiling - and he is cc&#39;d here.<br>
&gt;&gt;<br>
&gt;&gt; from what i recall, the v4 and v3 metrics are roughly similar in terms<br>
&gt;&gt; of speed and per iteration cost for computing the metric,<br>
&gt;&gt;<br>
&gt;&gt; assuming that you set up the metric in a similar manner.<br>
&gt;&gt;<br>
&gt;&gt; so , without seeing your v3 code,  we cannot understand what<br>
&gt;&gt; differences might exist in your v4 and v3 comparison.  one obvious<br>
&gt;&gt; question is per iteration cost of assessing the metric and how many<br>
&gt;&gt; points one is using in the call<br>
&gt;&gt;<br>
&gt;&gt; vRigidRegistration-&gt;SetMetricSamplingPercentage(0.1);<br>
&gt;&gt;<br>
&gt;&gt; relative to your v3 setup.<br>
&gt;&gt;<br>
&gt;&gt; the &quot;extra&quot; computation from the virtual domain and in the composite<br>
&gt;&gt; transform should be relatively little as the identity transform does<br>
&gt;&gt; not require any actual computation.<br>
&gt;&gt;<br>
&gt;&gt; just a few thoughts ---- perhaps others will have additional feedback.<br>
&gt;&gt;<br>
&gt;&gt; brian<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; On Thu, Oct 25, 2012 at 5:20 PM, lien lee &lt;<a href="mailto:lienlee@gmail.com">lienlee@gmail.com</a>&gt; wrote:<br>
&gt;&gt; &gt; Hi all,<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; As a starting point with v4, a simple rigid transform image registration<br>
&gt;&gt; &gt; (as<br>
&gt;&gt; &gt; attached at the bottom of this message) was created and tested on a pair<br>
&gt;&gt; &gt; of<br>
&gt;&gt; &gt; 256x256x187 and 256x256x229 images.  It takes about 90s.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; I had an same registration based on v3, and tested against the same<br>
&gt;&gt; &gt; data,<br>
&gt;&gt; &gt; but it just took about 12s on the same machine with almost the same<br>
&gt;&gt; &gt; matching<br>
&gt;&gt; &gt; result.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; As a newbie, I am not sure whether I did the right thing and I am trying<br>
&gt;&gt; &gt; to<br>
&gt;&gt; &gt; understand more about v4. By debugging into the v4 code, I noticed that:<br>
&gt;&gt; &gt; 1. the new virtual domain (same as the fixed image in my case)<br>
&gt;&gt; &gt; introduces<br>
&gt;&gt; &gt; one more layer which needs some extra computation.<br>
&gt;&gt; &gt; 2. the transformation on a point was done through two Transformxxx()<br>
&gt;&gt; &gt; operations by two transform instances in<br>
&gt;&gt; &gt; ImageToImageMetricv4::m_CompositeTransform, although one of which is<br>
&gt;&gt; &gt; actually an identity transform.<br>
&gt;&gt; &gt; and, I am guessing maybe they are reasons for more computing time, but,<br>
&gt;&gt; &gt; I am<br>
&gt;&gt; &gt; not so sure.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Of course, I can just stick to v3, but, I am just curious whether there<br>
&gt;&gt; &gt; are<br>
&gt;&gt; &gt; some ways that I can avoid those extra computations with v4.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; //=== Start of the code ===================================<br>
&gt;&gt; &gt; //<br>
&gt;&gt; &gt; bool<br>
&gt;&gt; &gt; RigidTransform(itk::CompositeTransform&lt;double,3&gt;::Pointer vComposite,<br>
&gt;&gt; &gt;     ImageType const&amp; vFixImage, ImageType const&amp; vMovImage)<br>
&gt;&gt; &gt; {<br>
&gt;&gt; &gt;     //- The Euler transform is a rotation and translation about a<br>
&gt;&gt; &gt; center, so<br>
&gt;&gt; &gt; we<br>
&gt;&gt; &gt;     //    need to find the rotation center.<br>
&gt;&gt; &gt;     //<br>
&gt;&gt; &gt;     typedef itk::Euler3DTransform&lt;double&gt; RigidTransformType;<br>
&gt;&gt; &gt;     RigidTransformType::Pointer vRigid = RigidTransformType::New();<br>
&gt;&gt; &gt;     typedef itk::CenteredTransformInitializer&lt;    RigidTransformType,<br>
&gt;&gt; &gt;                                                 ImageType,<br>
&gt;&gt; &gt;                                                 ImageType &gt;<br>
&gt;&gt; &gt; InitializerType;<br>
&gt;&gt; &gt;     InitializerType::Pointer Initializer = InitializerType::New();<br>
&gt;&gt; &gt;     Initializer-&gt;SetTransform(vRigid);<br>
&gt;&gt; &gt;     Initializer-&gt;SetFixedImage(&amp;vFixImage);<br>
&gt;&gt; &gt;     Initializer-&gt;SetMovingImage(&amp;vMovImage);<br>
&gt;&gt; &gt;     Initializer-&gt;GeometryOn();<br>
&gt;&gt; &gt;     Initializer-&gt;InitializeTransform();<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     vComposite-&gt;AddTransform(vRigid);<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     //- Metric<br>
&gt;&gt; &gt;     //<br>
&gt;&gt; &gt;     typedef itk::MattesMutualInformationImageToImageMetricv4&lt;ImageType,<br>
&gt;&gt; &gt; ImageType&gt; MetricType;<br>
&gt;&gt; &gt;     MetricType::Pointer vMetric = MetricType::New();<br>
&gt;&gt; &gt;     vMetric-&gt;SetNumberOfHistogramBins(32);<br>
&gt;&gt; &gt;     vMetric-&gt;SetUseFixedImageGradientFilter(false);<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     //- Optimizer<br>
&gt;&gt; &gt;     //<br>
&gt;&gt; &gt;     typedef itk::GradientDescentOptimizerv4 OptimizerType;<br>
&gt;&gt; &gt;     OptimizerType::Pointer vOptimizer = OptimizerType::New();<br>
&gt;&gt; &gt;     vOptimizer-&gt;SetNumberOfIterations( 50 );<br>
&gt;&gt; &gt;     vOptimizer-&gt;SetDoEstimateLearningRateOnce( true );<br>
&gt;&gt; &gt;     vOptimizer-&gt;SetMinimumConvergenceValue( 1e-6 );<br>
&gt;&gt; &gt;     vOptimizer-&gt;SetConvergenceWindowSize( 5 );<br>
&gt;&gt; &gt;     vOptimizer-&gt;SetMaximumStepSizeInPhysicalUnits( 0.5 );<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     //- Scale estimator<br>
&gt;&gt; &gt;     //<br>
&gt;&gt; &gt;     itk::OptimizerParameterScalesEstimator::Pointer vScalesEstimator;<br>
&gt;&gt; &gt;     typedef itk::RegistrationParameterScalesFromJacobian&lt;MetricType&gt;<br>
&gt;&gt; &gt; JacobianScalesEstimatorType;<br>
&gt;&gt; &gt;     {<br>
&gt;&gt; &gt;         JacobianScalesEstimatorType::Pointer vJacobianScalesEstimator<br>
&gt;&gt; &gt;           = JacobianScalesEstimatorType::New();<br>
&gt;&gt; &gt;         vJacobianScalesEstimator-&gt;SetMetric(vMetric);<br>
&gt;&gt; &gt;         vJacobianScalesEstimator-&gt;SetTransformForward(true);<br>
&gt;&gt; &gt;         vScalesEstimator = vJacobianScalesEstimator;<br>
&gt;&gt; &gt;     }<br>
&gt;&gt; &gt;     vOptimizer-&gt;SetScalesEstimator(vScalesEstimator);<br>
&gt;&gt; &gt;     vOptimizer-&gt;SetDoEstimateScales(true);<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     //- The RegistrationMethod class coordinates the registration<br>
&gt;&gt; &gt; operation.<br>
&gt;&gt; &gt;     //    It needs all the pieces that come together to perform the<br>
&gt;&gt; &gt; registration<br>
&gt;&gt; &gt;     //    operation.<br>
&gt;&gt; &gt;     //<br>
&gt;&gt; &gt;     typedef itk::ImageRegistrationMethodv4&lt;ImageType, ImageType,<br>
&gt;&gt; &gt; itk::Euler3DTransform&lt;double&gt;&gt; RigidRegistrationType;<br>
&gt;&gt; &gt;     RigidRegistrationType::Pointer vRigidRegistration =<br>
&gt;&gt; &gt; RigidRegistrationType::New();<br>
&gt;&gt; &gt;     vRigidRegistration-&gt;SetOptimizer(vOptimizer);<br>
&gt;&gt; &gt;     vRigidRegistration-&gt;SetFixedImage(&amp;vFixImage);<br>
&gt;&gt; &gt;     vRigidRegistration-&gt;SetMovingImage(&amp;vMovImage);<br>
&gt;&gt; &gt;     vRigidRegistration-&gt;SetMovingInitialTransform(vRigid);<br>
&gt;&gt; &gt;     vRigidRegistration-&gt;SetNumberOfLevels(3);<br>
&gt;&gt; &gt;     vRigidRegistration-&gt;SetMetric(vMetric);<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; vRigidRegistration-&gt;SetMetricSamplingStrategy(RigidRegistrationType::RANDOM);<br>
&gt;&gt; &gt;     vRigidRegistration-&gt;SetMetricSamplingPercentage(0.1);<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     //- Shrink the virtual domain by specified factors for each level.<br>
&gt;&gt; &gt;     //<br>
&gt;&gt; &gt;     RigidRegistrationType::ShrinkFactorsArrayType vRigidShrinkFactors;<br>
&gt;&gt; &gt;     vRigidShrinkFactors.SetSize( 3 );<br>
&gt;&gt; &gt;     vRigidShrinkFactors[0] = 4;<br>
&gt;&gt; &gt;     vRigidShrinkFactors[1] = 2;<br>
&gt;&gt; &gt;     vRigidShrinkFactors[2] = 1;<br>
&gt;&gt; &gt;     vRigidRegistration-&gt;SetShrinkFactorsPerLevel( vRigidShrinkFactors );<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     //- Smoothing sigmas array<br>
&gt;&gt; &gt;     //<br>
&gt;&gt; &gt;     RigidRegistrationType::SmoothingSigmasArrayType<br>
&gt;&gt; &gt; vRigidSmoothingSigmas;<br>
&gt;&gt; &gt;     vRigidSmoothingSigmas.SetSize(3);<br>
&gt;&gt; &gt;     vRigidSmoothingSigmas.Fill(0);<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; vRigidRegistration-&gt;SetSmoothingSigmasPerLevel(vRigidSmoothingSigmas);<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     //- Observer<br>
&gt;&gt; &gt;     //<br>
&gt;&gt; &gt;     typedef CommandIterationUpdate&lt; RigidRegistrationType &gt; CommandType;<br>
&gt;&gt; &gt;     CommandType::Pointer observer = CommandType::New();<br>
&gt;&gt; &gt;     vRigidRegistration-&gt;AddObserver( itk::InitializeEvent(), observer );<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     try<br>
&gt;&gt; &gt;     {<br>
&gt;&gt; &gt;         std::cout &lt;&lt; &quot;Starting rigid registration...&quot; &lt;&lt; std::endl;<br>
&gt;&gt; &gt;         vRigidRegistration-&gt;Update();<br>
&gt;&gt; &gt;         std::cout &lt;&lt; &quot;Rigid parameters after registration: &quot; &lt;&lt;<br>
&gt;&gt; &gt; std::endl<br>
&gt;&gt; &gt;                 &lt;&lt; vOptimizer-&gt;GetCurrentPosition() &lt;&lt; std::endl;<br>
&gt;&gt; &gt;     }<br>
&gt;&gt; &gt;     catch( itk::ExceptionObject &amp;e )<br>
&gt;&gt; &gt;     {<br>
&gt;&gt; &gt;         std::cerr &lt;&lt; &quot;Exception caught: &quot; &lt;&lt; e &lt;&lt; std::endl;<br>
&gt;&gt; &gt;         return false;<br>
&gt;&gt; &gt;     }<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; vComposite-&gt;AddTransform(const_cast&lt;RigidTransformType*&gt;(vRigidRegistration-&gt;GetOutput()-&gt;Get()));<br>
&gt;&gt; &gt;     return true;<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt; //<br>
&gt;&gt; &gt; //=== End of the code =====================================<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; _____________________________________<br>
&gt;&gt; &gt; Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Visit other Kitware open-source projects at<br>
&gt;&gt; &gt; <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Kitware offers ITK Training Courses, for more information visit:<br>
&gt;&gt; &gt; <a href="http://www.kitware.com/products/protraining.php" target="_blank">http://www.kitware.com/products/protraining.php</a><br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Please keep messages on-topic and check the ITK FAQ at:<br>
&gt;&gt; &gt; <a href="http://www.itk.org/Wiki/ITK_FAQ" target="_blank">http://www.itk.org/Wiki/ITK_FAQ</a><br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Follow this link to subscribe/unsubscribe:<br>
&gt;&gt; &gt; <a href="http://www.itk.org/mailman/listinfo/insight-users" target="_blank">http://www.itk.org/mailman/listinfo/insight-users</a><br>
&gt;&gt; &gt;<br>
&gt;<br>
&gt;<br>
</div></div></blockquote></div><br>