~ubuntu-branches/debian/sid/3depict/sid

« back to all changes in this revision

Viewing changes to src/filter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): D Haley
  • Date: 2010-09-22 20:09:24 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100922200924-bkyorwswrntnst4d
Tags: 0.0.2-1
* New upstream version
* Enable parallel build

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <wx/filename.h>
32
32
#include <wx/dir.h>
33
33
 
 
34
#ifdef _OPENMP
 
35
#include <omp.h>
 
36
#endif
 
37
 
34
38
using std::list;
35
39
using std::vector;
36
40
using std::string;
40
44
const unsigned int NUM_CALLBACK=50000;
41
45
const size_t MAX_IONS_LOAD_DEFAULT=5*1024*1024/sizeof(IONHIT); //5 MB worth.
42
46
 
43
 
const unsigned int NUM_COLOURMAPS=9;
44
47
const unsigned int MAX_NUM_COLOURS=256;
 
48
// Tp prevent the dropdown lists from getting too unwieldy, set an artificial maximum
 
49
const unsigned int MAX_NUM_FILE_COLS=5000; 
45
50
 
46
51
const unsigned int SPECTRUM_MAX_BINS=100000;
47
52
 
49
54
const char *STREAM_NAMES[] = { "Ion",
50
55
                                "Plot",
51
56
                                "Draw",
52
 
                                "Range"};
 
57
                                "Range",
 
58
                                "Voxel"};
53
59
 
54
60
//Key types for clipping 
55
61
enum
60
66
        KEY_IONCLIP_PRIMITIVE_SHOW,
61
67
        KEY_IONCLIP_PRIMITIVE_INVERTCLIP,
62
68
        KEY_IONCLIP_NORMAL,
63
 
        KEY_IONCLIP_ENABLED,
64
69
 
65
 
        KEY_IONCOLOURFILTER_ENABLED,
66
70
        KEY_IONCOLOURFILTER_COLOURMAP,
67
71
        KEY_IONCOLOURFILTER_MAPSTART,
68
72
        KEY_IONCOLOURFILTER_MAPEND,
69
73
        KEY_IONCOLOURFILTER_NCOLOURS,
70
74
 
71
 
        KEY_SPECTRUM_ENABLED,
72
75
        KEY_SPECTRUM_BINWIDTH,
73
76
        KEY_SPECTRUM_AUTOEXTREMA,
74
77
        KEY_SPECTRUM_MIN,
82
85
        KEY_POSLOAD_COLOUR,
83
86
        KEY_POSLOAD_IONSIZE,
84
87
        KEY_POSLOAD_ENABLED,
 
88
        KEY_POSLOAD_SELECTED_COLUMN0,
 
89
        KEY_POSLOAD_SELECTED_COLUMN1,
 
90
        KEY_POSLOAD_SELECTED_COLUMN2,
 
91
        KEY_POSLOAD_SELECTED_COLUMN3,
 
92
        KEY_POSLOAD_NUMBER_OF_COLUMNS,
85
93
 
86
 
        KEY_IONDOWNSAMPLE_ENABLED,
87
94
        KEY_IONDOWNSAMPLE_FRACTION,
88
95
        KEY_IONDOWNSAMPLE_FIXEDOUT,
89
96
        KEY_IONDOWNSAMPLE_COUNT,
93
100
        KEY_RANGE_START,
94
101
        KEY_RANGE_END,
95
102
 
96
 
        KEY_COMPPROFILE_ENABLED,
97
103
        KEY_COMPPROFILE_BINWIDTH,
98
104
        KEY_COMPPROFILE_FIXEDBINS,
99
105
        KEY_COMPPROFILE_NORMAL,
105
111
        KEY_COMPPROFILE_SHOWPRIMITIVE,
106
112
        KEY_COMPPROFILE_NORMALISE,
107
113
        KEY_COMPPROFILE_COLOUR,
 
114
        KEY_COMPPROFILE_ERRMODE,
 
115
        KEY_COMPPROFILE_AVGWINSIZE,
108
116
 
109
 
        KEY_BOUNDINGBOX_ENABLED,
110
117
        KEY_BOUNDINGBOX_VISIBLE,
111
118
        KEY_BOUNDINGBOX_COUNT_X,
112
119
        KEY_BOUNDINGBOX_COUNT_Y,
120
127
        KEY_BOUNDINGBOX_SPACING_Y,
121
128
        KEY_BOUNDINGBOX_SPACING_Z,
122
129
 
123
 
        KEY_TRANSFORM_ENABLED,
124
130
        KEY_TRANSFORM_MODE,
125
131
        KEY_TRANSFORM_SCALEFACTOR,
126
132
        KEY_TRANSFORM_ORIGIN,
 
133
        KEY_TRANSFORM_ORIGINMODE,
127
134
        KEY_TRANSFORM_ROTATE_ANGLE,
128
135
        KEY_TRANSFORM_ROTATE_AXIS,
 
136
        
129
137
 
130
 
        KEY_EXTERNALPROGRAM_ENABLED,
131
138
        KEY_EXTERNALPROGRAM_COMMAND,
132
139
        KEY_EXTERNALPROGRAM_WORKDIR,
133
140
        KEY_EXTERNALPROGRAM_ALWAYSCACHE,
134
141
 
135
 
        KEY_SPATIALANALYSIS_ENABLED,
136
142
        KEY_SPATIALANALYSIS_STOPMODE,
137
143
        KEY_SPATIALANALYSIS_ALGORITHM,
138
144
        KEY_SPATIALANALYSIS_DISTMAX,
139
145
        KEY_SPATIALANALYSIS_NNMAX,
140
146
 
 
147
        KEY_VOXEL_FIXEDWIDTH,
 
148
        KEY_VOXEL_NBINSX,
 
149
        KEY_VOXEL_NBINSY,
 
150
        KEY_VOXEL_NBINSZ,
 
151
        KEY_VOXEL_WIDTHBINSX,
 
152
        KEY_VOXEL_WIDTHBINSY,
 
153
        KEY_VOXEL_WIDTHBINSZ,
 
154
        KEY_VOXEL_COUNT_TYPE,
 
155
        KEY_VOXEL_NORMALISE_TYPE,
 
156
        KEY_VOXEL_SPOTSIZE,
 
157
        KEY_VOXEL_TRANSPARANCY,
 
158
        KEY_VOXEL_COLOUR,
 
159
        KEY_VOXEL_ISOLEVEL,
 
160
        KEY_VOXEL_REPRESENTATION_MODE,
 
161
        KEY_VOXEL_ENABLE_NUMERATOR,
 
162
        KEY_VOXEL_ENABLE_DENOMINATOR,
141
163
};
142
164
 
143
165
//Keys for binding IDs
181
203
        SPATIAL_DENSITY_ENUM_END
182
204
};
183
205
 
 
206
 
184
207
size_t numElements(const vector<const FilterStreamData *> &v)
185
208
{
186
209
        size_t nE=0;
232
255
        data.clear();
233
256
}
234
257
 
 
258
void VoxelStreamData::clear()
 
259
{
 
260
        data.clear();
 
261
}
 
262
 
235
263
void DrawStreamData::clear()
236
264
{
237
265
        for(unsigned int ui=0; ui<drawables.size(); ui++)
245
273
 
246
274
Filter::Filter()
247
275
{
248
 
        enabled=true;
249
276
        cacheOK=false;
250
277
        cache=true;
251
278
        progress=0;
279
306
        return cacheOK;
280
307
}
281
308
 
282
 
void Filter::getOutputData(vector<FilterStreamData *> * &getOut)
283
 
{
284
 
        getOut = &filterOutputs;        
285
 
}
286
 
 
287
309
void Filter::getSelectionDevices(vector<SelectionDevice *> &outD)
288
310
{
289
311
        outD.resize(devices.size());
290
312
 
291
313
        std::copy(devices.begin(),devices.end(),outD.begin());
 
314
 
 
315
#ifdef DEBUG
 
316
        for(unsigned int ui=0;ui<outD.size();ui++)
 
317
        {
 
318
                ASSERT(outD[ui]);
 
319
                //Ensure that pointers coming in are valid, by attempting to perform an operation on them
 
320
                vector<std::pair<const Filter *,SelectionBinding> > tmp;
 
321
                outD[ui]->getModifiedBindings(tmp);
 
322
                tmp.clear();
 
323
        }
 
324
#endif
292
325
}
293
326
 
294
327
void Filter::updateOutputInfo(const std::vector<const FilterStreamData *> &dataOut)
299
332
        
300
333
        //Count the different types of output stream.
301
334
        for(unsigned int ui=0;ui<dataOut.size();ui++)
 
335
        {
 
336
                ASSERT(getBitNum(dataOut[ui]->getStreamType()) < NUM_STREAM_TYPES);
302
337
                numStreamsLastRefresh[getBitNum(dataOut[ui]->getStreamType())]++;
 
338
        }
303
339
}
304
340
 
305
341
unsigned int Filter::getNumOutput(unsigned int streamType) const
306
342
{
307
343
        ASSERT(streamType < NUM_STREAM_TYPES);
308
344
        return numStreamsLastRefresh[streamType];
309
 
 
310
345
}
311
346
 
312
347
std::string Filter::getUserString() const
317
352
                return typeString();
318
353
}
319
354
 
 
355
void Filter::initFilter(const std::vector<const FilterStreamData *> &dataIn,
 
356
                                std::vector<const FilterStreamData *> &dataOut)
 
357
{
 
358
        dataOut.resize(dataIn.size());
 
359
        std::copy(dataIn.begin(),dataIn.end(),dataOut.begin());
 
360
}
 
361
 
 
362
 
320
363
// == Pos load filter ==
321
364
PosLoadFilter::PosLoadFilter()
322
365
{
323
 
    cache=true;
324
 
    maxIons=MAX_IONS_LOAD_DEFAULT;
325
 
    //default ion colour is red.
326
 
    r=a=1.0f;
327
 
    g=b=0.0f;
328
 
 
329
 
    enabled=true;
330
 
    volumeRestrict=false;
331
 
    bound.setInverseLimits();
332
 
    //Ion size is 1.0 units (rel. size).. 
333
 
    ionSize=2.0;
 
366
        cache=true;
 
367
        maxIons=MAX_IONS_LOAD_DEFAULT;
 
368
        fileType=FILE_TYPE_POS;
 
369
        //default ion colour is red.
 
370
        r=a=1.0f;
 
371
        g=b=0.0f;
 
372
 
 
373
        enabled=true;
 
374
        volumeRestrict=false;
 
375
        bound.setInverseLimits();
 
376
        //Ion size (rel. size)..
 
377
        ionSize=2.0;
 
378
 
 
379
        numColumns = 4;
 
380
        for (int i  = 0; i < numColumns; i++) {
 
381
                index[i] = i;
 
382
        }
334
383
}
335
384
 
336
385
Filter *PosLoadFilter::cloneUncached() const
345
394
        p->a=a; 
346
395
        p->bound.setBounds(bound);
347
396
        p->volumeRestrict=volumeRestrict;
 
397
        p->numColumns=numColumns;
 
398
        p->fileType=fileType;
 
399
        p->enabled=enabled;
 
400
 
 
401
        for(size_t ui=0;ui<INDEX_LENGTH;ui++)
 
402
                p->index[ui]=index[ui];
 
403
 
348
404
        //We are copying wether to cache or not,
349
405
        //not the cache itself
350
406
        p->cache=cache;
353
409
        p->progress=progress;
354
410
        p->userString=userString;
355
411
 
 
412
        // this is for a pos file
 
413
        memcpy(p->index, index, sizeof(int) * 4);
 
414
        p->numColumns=numColumns;
 
415
 
356
416
        return p;
357
417
}
358
418
 
359
419
void PosLoadFilter::setFilename(const char *name)
360
420
{
361
421
        ionFilename = name;
 
422
        guessNumColumns();
362
423
}
363
424
 
364
425
void PosLoadFilter::setFilename(const std::string &name)
365
426
{
366
427
        ionFilename = name;
 
428
        guessNumColumns();
 
429
}
 
430
 
 
431
void PosLoadFilter::guessNumColumns()
 
432
{
 
433
        //Test the extention to determine what we will do
 
434
        string extension;
 
435
        if(ionFilename.size() > 4)
 
436
                extension = ionFilename.substr ( ionFilename.size() - 4, 4 );
 
437
 
 
438
        //Set extention to lowercase version
 
439
        for(size_t ui=0;ui<extension.size();ui++)
 
440
                extension[ui] = tolower(extension[ui]);
 
441
 
 
442
        if( extension == std::string(".pos")) {
 
443
                numColumns = 4;
 
444
                fileType = FILE_TYPE_POS;
 
445
                return;
 
446
        }
 
447
        fileType = FILE_TYPE_NULL;
 
448
        numColumns = 4;
367
449
}
368
450
 
369
451
//!Get (approx) number of bytes required for cache
380
462
        return result;  
381
463
}
382
464
 
 
465
string PosLoadFilter::getValueLabel()
 
466
{
 
467
        return std::string("Mass-to-Charge (amu/e)");
 
468
}
 
469
 
383
470
unsigned int PosLoadFilter::refresh(const std::vector<const FilterStreamData *> &dataIn,
384
471
        std::vector<const FilterStreamData *> &getOut, unsigned int &progress, bool (*callback)(void))
385
472
{
396
483
                return 0;
397
484
        }
398
485
 
 
486
        if(!enabled)
 
487
        {
 
488
                for(unsigned int ui=0;ui<dataIn.size();ui++)
 
489
                        getOut.push_back(dataIn[ui]);
 
490
 
 
491
                return 0;
 
492
        }
 
493
 
399
494
        IonStreamData *ionData = new IonStreamData;
400
495
 
401
496
 
402
 
        int index[4] = {
403
 
                0, 1, 2, 3};
404
497
        unsigned int uiErr;     
405
498
        if(!volumeRestrict)
406
499
        {
407
500
                if(maxIons)
408
501
                {
409
502
                        //Load the pos file, limiting how much you pull from it
410
 
                        if((uiErr = LimitLoadPosFile(4, index, ionData->data, ionFilename.c_str(),
 
503
                        if((uiErr = LimitLoadPosFile(numColumns, INDEX_LENGTH, index, ionData->data, ionFilename.c_str(),
411
504
                                                                maxIons,progress,callback)))
412
505
                        {
413
506
                                clearCache();
418
511
                else
419
512
                {
420
513
                        //Load the pos file
421
 
                        if((uiErr = GenericLoadFloatFile(4, index, ionData->data, ionFilename.c_str(),
 
514
                        if((uiErr = GenericLoadFloatFile(numColumns, INDEX_LENGTH, index, ionData->data, ionFilename.c_str(),
422
515
                                                                progress,callback)))
423
516
                        {
424
517
                                clearCache();
461
554
        ionData->b = b;
462
555
        ionData->a = a;
463
556
        ionData->ionSize=ionSize;
 
557
        ionData->valueType=getValueLabel();
464
558
 
465
559
        if(cache)
466
560
        {
474
568
        for(unsigned int ui=0;ui<dataIn.size();ui++)
475
569
                getOut.push_back(dataIn[ui]);
476
570
 
477
 
 
478
571
        //Append the ion data 
479
572
        getOut.push_back(ionData);
480
573
 
493
586
        s.push_back(std::make_pair("File", ionFilename));
494
587
        type.push_back(PROPERTY_TYPE_STRING);
495
588
        keys.push_back(KEY_POSLOAD_FILE);
 
589
        
 
590
        string colStr;
 
591
        stream_cast(colStr,numColumns);
 
592
        s.push_back(std::make_pair("Number of columns", colStr));
 
593
        keys.push_back(KEY_POSLOAD_NUMBER_OF_COLUMNS);
 
594
        type.push_back(PROPERTY_TYPE_INTEGER);
496
595
 
 
596
        vector<pair<unsigned int,string> > choices;
 
597
        for (int i = 0; i < numColumns; i++) {
 
598
                string tmp;
 
599
                stream_cast(tmp,i);
 
600
                choices.push_back(make_pair(i,tmp));
 
601
        }
 
602
        
 
603
        colStr= choiceString(choices,index[0]);
 
604
        s.push_back(std::make_pair("x", colStr));
 
605
        keys.push_back(KEY_POSLOAD_SELECTED_COLUMN0);
 
606
        type.push_back(PROPERTY_TYPE_CHOICE);
 
607
        
 
608
        colStr= choiceString(choices,index[1]);
 
609
        s.push_back(std::make_pair("y", colStr));
 
610
        keys.push_back(KEY_POSLOAD_SELECTED_COLUMN1);
 
611
        type.push_back(PROPERTY_TYPE_CHOICE);
 
612
        
 
613
        colStr= choiceString(choices,index[2]);
 
614
        s.push_back(std::make_pair("z", colStr));
 
615
        keys.push_back(KEY_POSLOAD_SELECTED_COLUMN2);
 
616
        type.push_back(PROPERTY_TYPE_CHOICE);
 
617
        
 
618
        colStr= choiceString(choices,index[3]);
 
619
        s.push_back(std::make_pair("value", colStr));
 
620
        keys.push_back(KEY_POSLOAD_SELECTED_COLUMN3);
 
621
        type.push_back(PROPERTY_TYPE_CHOICE);
 
622
        
497
623
        string tmpStr;
498
624
        stream_cast(tmpStr,enabled);
499
625
        s.push_back(std::make_pair("Enabled", tmpStr));
531
657
bool PosLoadFilter::setProperty( unsigned int set, unsigned int key, 
532
658
                                        const std::string &value, bool &needUpdate)
533
659
{
 
660
        
 
661
        needUpdate=false;
534
662
        switch(key)
535
663
        {
536
664
                case KEY_POSLOAD_FILE:
575
703
                        if(stream_cast(ltmp,value))
576
704
                                return false;
577
705
 
578
 
                        if(ltmp*1024*1024/sizeof(IONHIT) != maxIons)
 
706
                        if(ltmp*(1024*1024/sizeof(IONHIT)) != maxIons)
579
707
                        {
580
708
                                //Convert from MB to ions.                      
581
 
                                maxIons = ltmp*1024*1024/sizeof(IONHIT);
 
709
                                maxIons = ltmp*(1024*1024/sizeof(IONHIT));
582
710
                                needUpdate=true;
583
711
                                //Invalidate cache
584
712
                                clearCache();
594
722
                        if(newB != b || newR != r ||
595
723
                                newG !=g || newA != a)
596
724
                        {
597
 
                                needUpdate=true;
598
725
                                r=newR/255.0;
599
726
                                g=newG/255.0;
600
727
                                b=newB/255.0;
601
728
                                a=newA/255.0;
602
729
 
603
 
                                clearCache();
 
730
 
 
731
                                //Check the cache, updating it if needed
 
732
                                if(cacheOK)
 
733
                                {
 
734
                                        for(unsigned int ui=0;ui<filterOutputs.size();ui++)
 
735
                                        {
 
736
                                                if(filterOutputs[ui]->getStreamType() == STREAM_TYPE_IONS)
 
737
                                                {
 
738
                                                        IonStreamData *i;
 
739
                                                        i=(IonStreamData *)filterOutputs[ui];
 
740
                                                        i->r=r;
 
741
                                                        i->g=g;
 
742
                                                        i->b=b;
 
743
                                                        i->a=a;
 
744
                                                }
 
745
                                        }
 
746
 
 
747
                                }
 
748
                                needUpdate=true;
604
749
                        }
 
750
 
 
751
 
605
752
                        break;
606
753
                }
607
754
                case KEY_POSLOAD_IONSIZE:
616
763
 
617
764
                        ionSize=ltmp;
618
765
                        needUpdate=true;
619
 
                        clearCache();
620
 
 
 
766
 
 
767
                        //Check the cache, updating it if needed
 
768
                        if(cacheOK)
 
769
                        {
 
770
                                for(unsigned int ui=0;ui<filterOutputs.size();ui++)
 
771
                                {
 
772
                                        if(filterOutputs[ui]->getStreamType() == STREAM_TYPE_IONS)
 
773
                                        {
 
774
                                                IonStreamData *i;
 
775
                                                i=(IonStreamData *)filterOutputs[ui];
 
776
                                                i->ionSize=ionSize;
 
777
                                        }
 
778
                                }
 
779
                        }
 
780
                        needUpdate=true;
 
781
 
 
782
                        break;
 
783
                }
 
784
                case KEY_POSLOAD_SELECTED_COLUMN0:
 
785
                {
 
786
                        std::string tmp;
 
787
                        int ltmp;
 
788
                        if(stream_cast(ltmp,value))
 
789
                                return false;
 
790
                        
 
791
                        if(ltmp < 0 || ltmp >= numColumns)
 
792
                                return false;
 
793
                        
 
794
                        index[0]=ltmp;
 
795
                        needUpdate=true;
 
796
                        clearCache();
 
797
                        
 
798
                        break;
 
799
                }
 
800
                case KEY_POSLOAD_SELECTED_COLUMN1:
 
801
                {
 
802
                        std::string tmp;
 
803
                        int ltmp;
 
804
                        if(stream_cast(ltmp,value))
 
805
                                return false;
 
806
                        
 
807
                        if(ltmp < 0 || ltmp >= numColumns)
 
808
                                return false;
 
809
                        
 
810
                        index[1]=ltmp;
 
811
                        needUpdate=true;
 
812
                        clearCache();
 
813
                        
 
814
                        break;
 
815
                }
 
816
                case KEY_POSLOAD_SELECTED_COLUMN2:
 
817
                {
 
818
                        std::string tmp;
 
819
                        int ltmp;
 
820
                        if(stream_cast(ltmp,value))
 
821
                                return false;
 
822
                        
 
823
                        if(ltmp < 0 || ltmp >= numColumns)
 
824
                                return false;
 
825
                        
 
826
                        index[2]=ltmp;
 
827
                        needUpdate=true;
 
828
                        clearCache();
 
829
                        
 
830
                        break;
 
831
                }
 
832
                case KEY_POSLOAD_SELECTED_COLUMN3:
 
833
                {
 
834
                        std::string tmp;
 
835
                        unsigned int ltmp;
 
836
                        if(stream_cast(ltmp,value))
 
837
                                return false;
 
838
                        
 
839
                        if(ltmp < 0 || ltmp >= numColumns)
 
840
                                return false;
 
841
                        
 
842
                        index[3]=ltmp;
 
843
                        needUpdate=true;
 
844
                        clearCache();
 
845
                        
 
846
                        break;
 
847
                }
 
848
                case KEY_POSLOAD_NUMBER_OF_COLUMNS:
 
849
                {
 
850
                        std::string tmp;
 
851
                        int ltmp;
 
852
                        if(stream_cast(ltmp,value))
 
853
                                return false;
 
854
                        
 
855
                        if(ltmp <=0 || ltmp >= MAX_NUM_FILE_COLS)
 
856
                                return false;
 
857
                        
 
858
                        numColumns=ltmp;
 
859
                        for (int i = 0; i < INDEX_LENGTH; i++) {
 
860
                                index[i] = (index[i] < numColumns? index[i]: numColumns - 1);
 
861
                        }
 
862
                        needUpdate=true;
 
863
                        clearCache();
 
864
                        
621
865
                        break;
622
866
                }
623
867
                default:
647
891
                return false;
648
892
        ionFilename=(char *)xmlString;
649
893
        xmlFree(xmlString);
650
 
 
651
 
 
 
894
        
 
895
        //Retrieve number of columns    
 
896
        if(XMLHelpFwdToElem(nodePtr,"columns"))
 
897
                return false;
 
898
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"value");
 
899
        if(!xmlString)
 
900
                return false;
 
901
        string s1((char *)xmlString);
 
902
        if(stream_cast(numColumns,s1))
 
903
                return false;
 
904
        xmlFree(xmlString);
 
905
 
 
906
        if(numColumns <=0 || numColumns >= MAX_NUM_FILE_COLS)
 
907
                return false;
 
908
        
 
909
        //Retrieve index        
 
910
        if(XMLHelpFwdToElem(nodePtr,"xyzm"))
 
911
                return false;
 
912
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"values");
 
913
        if(!xmlString)
 
914
                return false;
 
915
        std::vector<string> v;
 
916
        splitStrsRef((char *)xmlString,',',v);
 
917
        for (int i = 0; i < INDEX_LENGTH && i < v.size(); i++)
 
918
        {
 
919
                if(stream_cast(index[i],v[i]))
 
920
                        return false;
 
921
 
 
922
                if(index[i] >=numColumns)
 
923
                        return false;
 
924
        }
 
925
        xmlFree(xmlString);
 
926
        
652
927
        //Retreive enabled/disabled
653
928
        //===
654
929
        if(XMLHelpFwdToElem(nodePtr,"enabled"))
757
1032
                return false;
758
1033
 
759
1034
        //check positive or zero
760
 
        if(ionSize < 0)
 
1035
        if(ionSize <=0)
761
1036
                return false;
762
1037
 
763
1038
        xmlFree(xmlString);
782
1057
 
783
1058
                        f << tabs(depth+1) << "<userstring value=\""<<userString << "\"/>"  << endl;
784
1059
                        f << tabs(depth+1) << "<file name=\"" << ionFilename << "\"/>" << endl;
 
1060
                        f << tabs(depth+1) << "<columns value=\"" << numColumns << "\"/>" << endl;
 
1061
                        f << tabs(depth+1) << "<xyzm values=\"" << index[0] << "," << index[1] << "," << index[2] << "," << index[3] << "\"/>" << endl;
785
1062
                        f << tabs(depth+1) << "<enabled value=\"" << enabled<< "\"/>" << endl;
786
1063
                        f << tabs(depth+1) << "<maxions value=\"" << maxIons << "\"/>" << endl;
787
1064
 
826
1103
        //not the cache itself
827
1104
        p->cache=cache;
828
1105
        p->cacheOK=false;
829
 
        p->enabled=enabled;
830
1106
        p->progress=progress;
831
1107
        p->userString=userString;
 
1108
        p->fixedNumOut=fixedNumOut;
832
1109
        return p;
833
1110
}
834
1111
 
853
1130
        //use the cached copy if we have it.
854
1131
        if(cacheOK)
855
1132
        {
856
 
                for(unsigned int ui=0;ui<dataIn.size();ui++)
 
1133
                for(size_t ui=0;ui<dataIn.size();ui++)
857
1134
                {
858
1135
                        if(dataIn[ui]->getStreamType() != STREAM_TYPE_IONS)
859
1136
                                getOut.push_back(dataIn[ui]);
860
1137
                }
861
 
                for(unsigned int ui=0;ui<filterOutputs.size();ui++)
 
1138
                for(size_t ui=0;ui<filterOutputs.size();ui++)
862
1139
                        getOut.push_back(filterOutputs[ui]);
863
1140
                return 0;
864
1141
        }
865
1142
 
866
1143
        clearCache();
867
1144
 
 
1145
 
 
1146
        size_t numIons=0;
 
1147
        for(unsigned int ui=0;ui<dataIn.size() ;ui++)
 
1148
        {
 
1149
                if(dataIn[ui]->getStreamType() == STREAM_TYPE_IONS)
 
1150
                                numIons++;
 
1151
        }
 
1152
 
868
1153
        size_t totalSize = numElements(dataIn);
869
 
        for(unsigned int ui=0;ui<dataIn.size() ;ui++)
 
1154
        for(size_t ui=0;ui<dataIn.size() ;ui++)
870
1155
        {
871
1156
                switch(dataIn[ui]->getStreamType())
872
1157
                {
879
1164
                                        if(fixedNumOut)
880
1165
                                        {
881
1166
                                                randomSelect(d->data,((const IonStreamData *)dataIn[ui])->data,
882
 
                                                                        rng,maxAfterFilter,progress,callback);
 
1167
                                                                        rng,maxAfterFilter/numIons,progress,callback);
883
1168
                                        }
884
1169
                                        else
885
1170
                                        {
889
1174
 
890
1175
                                                //highly unlikely with even modest numbers of ions
891
1176
                                                //that this will not be exceeeded
892
 
                                                d->data.reserve(fraction/1.2*totalSize);
 
1177
                                                d->data.reserve(fraction/1.1*totalSize);
893
1178
 
894
1179
                                                ASSERT(dataIn[ui]->getStreamType() == STREAM_TYPE_IONS);
895
1180
 
927
1212
                                d->a =((IonStreamData *)dataIn[ui])->a;
928
1213
                                d->ionSize =((IonStreamData *)dataIn[ui])->ionSize;
929
1214
                                d->representationType=((IonStreamData *)dataIn[ui])->representationType;
 
1215
                                d->valueType=((IonStreamData *)dataIn[ui])->valueType;
930
1216
 
931
1217
                                //getOut is const, so shouldn't be modified
932
1218
                                if(cache)
965
1251
        vector<pair<string,string> > s;
966
1252
 
967
1253
        string tmpStr;
968
 
        stream_cast(tmpStr,enabled);
969
 
        s.push_back(std::make_pair("Enabled", tmpStr));
970
 
        keys.push_back(KEY_IONDOWNSAMPLE_ENABLED);
971
 
        type.push_back(PROPERTY_TYPE_BOOL);
972
 
 
973
1254
        stream_cast(tmpStr,fixedNumOut);
974
1255
        s.push_back(std::make_pair("By Count", tmpStr));
975
1256
        keys.push_back(KEY_IONDOWNSAMPLE_FIXEDOUT);
1003
1284
        needUpdate=false;
1004
1285
        switch(key)
1005
1286
        {
1006
 
                case KEY_IONDOWNSAMPLE_ENABLED:
1007
 
                {
1008
 
                        string stripped=stripWhite(value);
1009
 
 
1010
 
                        if(!(stripped == "1"|| stripped == "0"))
1011
 
                                return false;
1012
 
 
1013
 
                        bool lastVal=enabled;
1014
 
                        if(stripped=="1")
1015
 
                                enabled=true;
1016
 
                        else
1017
 
                                enabled=false;
1018
 
 
1019
 
                        //if the result is different, the
1020
 
                        //cache should be invalidated
1021
 
                        if(lastVal!=enabled)
1022
 
                        {
1023
 
                                needUpdate=true;
1024
 
                                clearCache();
1025
 
                        }
1026
 
 
1027
 
                        break;
1028
 
 
1029
 
                }
1030
1287
                case KEY_IONDOWNSAMPLE_FIXEDOUT: 
1031
1288
                {
1032
1289
                        string stripped=stripWhite(value);
1216
1473
        return true;
1217
1474
 
1218
1475
}
 
1476
 
 
1477
 
 
1478
// == Voxels filter ==
 
1479
//TODO
 
1480
VoxeliseFilter::VoxeliseFilter() 
 
1481
: fixedWidth(false), bc(), normaliseType(VOXEL_NORMALISETYPE_NONE)
 
1482
{
 
1483
        splatSize=1.0f;
 
1484
        a=0.9f;
 
1485
        r=g=b=0.5;
 
1486
        isoLevel=0.5;
 
1487
        bc.setBounds(0, 0, 0, 1, 1, 1);
 
1488
        representation=VOXEL_REPRESENT_POINTCLOUD;
 
1489
        for (int i = 0; i < INDEX_LENGTH; i++) {
 
1490
                nBins[i] = 50;
 
1491
        }
 
1492
        calculateWidthsFromNumBins(binWidth, nBins);
 
1493
        numeratorAll = false;
 
1494
        denominatorAll = true;
 
1495
 
 
1496
        rsdIncoming=0;
 
1497
}
 
1498
 
 
1499
 
 
1500
Filter *VoxeliseFilter::cloneUncached() const
 
1501
{
 
1502
        VoxeliseFilter *p=new VoxeliseFilter();
 
1503
        p->splatSize=splatSize;
 
1504
        p->a=a;
 
1505
        p->r=r;
 
1506
        p->g=g;
 
1507
        p->b=b;
 
1508
        
 
1509
        p->isoLevel=isoLevel;
 
1510
        p->representation=representation;
 
1511
        p->splatSize=splatSize;
 
1512
 
 
1513
        p->numeratorAll=numeratorAll;
 
1514
        p->denominatorAll=denominatorAll;
 
1515
 
 
1516
        p->bc=bc;
 
1517
 
 
1518
        for(size_t ui=0;ui<INDEX_LENGTH;ui++)
 
1519
        {
 
1520
                p->nBins[ui] = nBins[ui];
 
1521
                p->binWidth[ui] = binWidth[ui];
 
1522
        }
 
1523
 
 
1524
        p->enabledIons[0].resize(enabledIons[0].size());
 
1525
        std::copy(enabledIons[0].begin(),enabledIons[0].end(),p->enabledIons[0].begin());
 
1526
        
 
1527
        p->enabledIons[1].resize(enabledIons[1].size());
 
1528
        std::copy(enabledIons[1].begin(),enabledIons[1].end(),p->enabledIons[1].begin());
 
1529
 
 
1530
        if(rsdIncoming)
 
1531
        {
 
1532
                p->rsdIncoming=new RangeStreamData();
 
1533
                *(p->rsdIncoming) = *rsdIncoming;
 
1534
        }
 
1535
        else
 
1536
                p->rsdIncoming=0;
 
1537
 
 
1538
        return p;
 
1539
}
 
1540
 
 
1541
//TODO
 
1542
size_t VoxeliseFilter::numBytesForCache(size_t nObjects) const
 
1543
{
 
1544
        return 0;
 
1545
}
 
1546
 
 
1547
void VoxeliseFilter::initFilter(const std::vector<const FilterStreamData *> &dataIn,
 
1548
                                                std::vector<const FilterStreamData *> &dataOut)
 
1549
{
 
1550
        const RangeStreamData *c=0;
 
1551
        //Determine if we have an incoming range
 
1552
        for (size_t i = 0; i < dataIn.size(); i++) 
 
1553
        {
 
1554
                if(dataIn[i]->getStreamType() == STREAM_TYPE_RANGE)
 
1555
                {
 
1556
                        c=(const RangeStreamData *)dataIn[i];
 
1557
 
 
1558
                        break;
 
1559
                }
 
1560
        }
 
1561
 
 
1562
        //we no longer (or never did) have any incoming ranges. Not much to do
 
1563
        if(!c)
 
1564
        {
 
1565
                //delete the old incoming range pointer
 
1566
                if(rsdIncoming)
 
1567
                        delete rsdIncoming;
 
1568
                rsdIncoming=0;
 
1569
 
 
1570
                enabledIons[0].clear(); //clear numerator options
 
1571
                enabledIons[1].clear(); //clear denominator options
 
1572
        }
 
1573
        else
 
1574
        {
 
1575
 
 
1576
 
 
1577
                //If we didn't have an incoming rsd, then make one up!
 
1578
                if(!rsdIncoming)
 
1579
                {
 
1580
                        rsdIncoming = new RangeStreamData;
 
1581
                        *rsdIncoming=*c;
 
1582
 
 
1583
                        //set the numerator to all disabled
 
1584
                        enabledIons[0].resize(rsdIncoming->rangeFile->getNumIons(),0);
 
1585
                        //set the denominator to have all enabled
 
1586
                        enabledIons[1].resize(rsdIncoming->rangeFile->getNumIons(),1);
 
1587
                }
 
1588
                else
 
1589
                {
 
1590
 
 
1591
                        //OK, so we have a range incoming already (from last time)
 
1592
                        //-- the question is, is it the same
 
1593
                        //one we had before 
 
1594
                        //Do a pointer comparison (its a hack, yes, but it should work)
 
1595
                        if(rsdIncoming->rangeFile != c->rangeFile)
 
1596
                        {
 
1597
                                //hmm, it is different. well, trash the old incoming rng
 
1598
                                delete rsdIncoming;
 
1599
 
 
1600
                                rsdIncoming = new RangeStreamData;
 
1601
                                *rsdIncoming=*c;
 
1602
 
 
1603
                                //set the numerator to all disabled
 
1604
                                enabledIons[0].resize(rsdIncoming->rangeFile->getNumIons(),0);
 
1605
                                //set the denominator to have all enabled
 
1606
                                enabledIons[1].resize(rsdIncoming->rangeFile->getNumIons(),1);
 
1607
                        }
 
1608
                }
 
1609
 
 
1610
        }
 
1611
}
 
1612
 
 
1613
// TODO: create plotstream
 
1614
unsigned int VoxeliseFilter::refresh(const std::vector<const FilterStreamData *> &dataIn,
 
1615
                                                                                  std::vector<const FilterStreamData *> &getOut, unsigned int &progress, bool (*callback)(void))
 
1616
{       
 
1617
 
 
1618
        Point3D minP,maxP;
 
1619
 
 
1620
        bc.setInverseLimits();
 
1621
                
 
1622
        for (size_t i = 0; i < dataIn.size(); i++) 
 
1623
        {
 
1624
                //Check for ion stream types. Block others from propagation.
 
1625
                if (dataIn[i]->getStreamType() != STREAM_TYPE_IONS) continue;
 
1626
 
 
1627
                const IonStreamData *is = (const IonStreamData *)dataIn[i];
 
1628
                //Don't work on empty or single object streams (bounding box needs to be defined)
 
1629
                if (is->GetNumBasicObjects() < 2) continue;
 
1630
        
 
1631
                //Build a bounding box  
 
1632
                dataLimits(is->data,minP,maxP);
 
1633
 
 
1634
                BoundCube bcTmp;
 
1635
                bcTmp.setBounds(minP,maxP);
 
1636
 
 
1637
                //Bounds could be invalid if, for example, we had coplanar axis aligned points
 
1638
                if (!bcTmp.isValid()) continue;
 
1639
                bc.expand(bcTmp);
 
1640
        }
 
1641
        //No bounding box? Tough cookies
 
1642
        if (!bc.isValid()) return VOXEL_BOUNDS_INVALID_ERR;
 
1643
 
 
1644
        bc.getBounds(minP,maxP);        
 
1645
        if (fixedWidth) 
 
1646
                calculateNumBinsFromWidths(binWidth, nBins);
 
1647
        else
 
1648
                calculateWidthsFromNumBins(binWidth, nBins);
 
1649
        
 
1650
        //Disallow empty bounding boxes (ie, produce no output)
 
1651
        if(minP == maxP)
 
1652
                return 0;
 
1653
                
 
1654
        VoxelStreamData *vs = new VoxelStreamData();
 
1655
        vs->cached = false;
 
1656
        vs->data.setCallbackMethod(callback);
 
1657
        vs->data.init(nBins[0], nBins[1], nBins[2], bc);
 
1658
        vs->representationType= representation;
 
1659
        vs->splatSize = splatSize;
 
1660
        vs->isoLevel=isoLevel;
 
1661
        vs->data.fill(0);
 
1662
        vs->r=r;
 
1663
        vs->g=g;
 
1664
        vs->b=b;
 
1665
        vs->a=a;
 
1666
 
 
1667
        VoxelStreamData *vsDenom = NULL;
 
1668
        if (normaliseType == VOXEL_NORMALISETYPE_COUNT2INVOXEL ||
 
1669
                normaliseType == VOXEL_NORMALISETYPE_ALLATOMSINVOXEL) {
 
1670
                //Check we actually have incoming data
 
1671
                ASSERT(rsdIncoming);
 
1672
                vsDenom = new VoxelStreamData();
 
1673
                vsDenom->cached = false;
 
1674
                vsDenom->data.setCallbackMethod(callback);
 
1675
                vsDenom->data.init(nBins[0], nBins[1], nBins[2], bc);
 
1676
                vsDenom->representationType= representation;
 
1677
                vsDenom->splatSize = splatSize;
 
1678
                vsDenom->isoLevel=isoLevel;
 
1679
                vsDenom->data.fill(0);
 
1680
                vsDenom->a=a;
 
1681
        }
 
1682
 
 
1683
        const IonStreamData *is;
 
1684
        if(rsdIncoming)
 
1685
        {
 
1686
 
 
1687
                for (size_t i = 0; i < dataIn.size(); i++) 
 
1688
                {
 
1689
                        
 
1690
                        //Check for ion stream types. Don't use anything else in counting
 
1691
                        if (dataIn[i]->getStreamType() != STREAM_TYPE_IONS) continue;
 
1692
                        
 
1693
                        is= (const IonStreamData *)dataIn[i];
 
1694
 
 
1695
                        
 
1696
                        //Count the numerator ions      
 
1697
                        if(is->data.size())
 
1698
                        {
 
1699
                                //Check what Ion type this stream belongs to. Assume all ions
 
1700
                                //in the stream belong to the same group
 
1701
                                unsigned int ionID;
 
1702
                                ionID = rsdIncoming->rangeFile->getIonID(is->data[0].getMassToCharge());
 
1703
 
 
1704
                                bool thisIonEnabled;
 
1705
                                if(ionID!=(unsigned int)-1)
 
1706
                                        thisIonEnabled=enabledIons[0][ionID];
 
1707
                                else
 
1708
                                        thisIonEnabled=false;
 
1709
 
 
1710
                                if(thisIonEnabled)
 
1711
                                        vs->data.countPoints(is->data,true,false);
 
1712
                        }
 
1713
                
 
1714
                        //If the user requests normalisation, compute the denominator datset
 
1715
                        if (normaliseType == VOXEL_NORMALISETYPE_COUNT2INVOXEL) {
 
1716
                                if(is->data.size())
 
1717
                                {
 
1718
                                        //Check what Ion type this stream belongs to. Assume all ions
 
1719
                                        //in the stream belong to the same group
 
1720
                                        unsigned int ionID;
 
1721
                                        ionID = rsdIncoming->rangeFile->getIonID(is->data[0].getMassToCharge());
 
1722
 
 
1723
                                        bool thisIonEnabled;
 
1724
                                        if(ionID!=(unsigned int)-1)
 
1725
                                                thisIonEnabled=enabledIons[1][ionID];
 
1726
                                        else
 
1727
                                                thisIonEnabled=false;
 
1728
 
 
1729
                                        if(thisIonEnabled)
 
1730
                                                vsDenom->data.countPoints(is->data,true,false);
 
1731
                                }
 
1732
                        } else if (normaliseType == VOXEL_NORMALISETYPE_ALLATOMSINVOXEL)
 
1733
                                vsDenom->data.countPoints(is->data,true,false);
 
1734
 
 
1735
                        if(!(*callback)())
 
1736
                        {
 
1737
                                delete vs;
 
1738
                                return VOXEL_ABORT_ERR;
 
1739
                        }
 
1740
                }
 
1741
        
 
1742
                //Perform normalsiation 
 
1743
                if (normaliseType == VOXEL_NORMALISETYPE_VOLUME)
 
1744
                        vs->data.calculateDensity();
 
1745
                else if (normaliseType == VOXEL_NORMALISETYPE_COUNT2INVOXEL ||
 
1746
                                 normaliseType == VOXEL_NORMALISETYPE_ALLATOMSINVOXEL)
 
1747
                        vs->data /= vsDenom->data;
 
1748
        }
 
1749
        else
 
1750
        {
 
1751
                //No range data.  Just count
 
1752
                for (size_t i = 0; i < dataIn.size(); i++) 
 
1753
                {
 
1754
                        
 
1755
                        is= (const IonStreamData *)dataIn[i];
 
1756
                        vs->data.countPoints(is->data,true,false);
 
1757
                        
 
1758
                        if(!(*callback)())
 
1759
                        {
 
1760
                                delete vs;
 
1761
                                return VOXEL_ABORT_ERR;
 
1762
                        }
 
1763
                }
 
1764
                ASSERT(normaliseType != VOXEL_NORMALISETYPE_COUNT2INVOXEL
 
1765
                                && normaliseType!=VOXEL_NORMALISETYPE_ALLATOMSINVOXEL);
 
1766
                if (normaliseType == VOXEL_NORMALISETYPE_VOLUME)
 
1767
                        vs->data.calculateDensity();
 
1768
        }       
 
1769
        delete vsDenom;
 
1770
        
 
1771
        getOut.push_back(vs);
 
1772
 
 
1773
        return 0;
 
1774
}
 
1775
 
 
1776
std::string VoxeliseFilter::getNormaliseTypeString(int type) const {
 
1777
        switch (type) {
 
1778
                case VOXEL_NORMALISETYPE_NONE:
 
1779
                        return std::string("None (Raw count)");
 
1780
                        break;
 
1781
                case VOXEL_NORMALISETYPE_VOLUME:
 
1782
                        return std::string("Volume (Density)");
 
1783
                        break;
 
1784
                case VOXEL_NORMALISETYPE_COUNT2INVOXEL:
 
1785
                        return std::string("Ratio (Num/Denom)");
 
1786
                        break;
 
1787
                case VOXEL_NORMALISETYPE_ALLATOMSINVOXEL:
 
1788
                        return std::string("All Ions (conc)");
 
1789
                        break;
 
1790
                default:
 
1791
                        return "";
 
1792
                        break;
 
1793
        }
 
1794
}
 
1795
 
 
1796
std::string VoxeliseFilter::getRepresentTypeString(int type) const {
 
1797
        switch (type) {
 
1798
                case VOXEL_REPRESENT_POINTCLOUD:
 
1799
                        return std::string("Point Cloud");
 
1800
                        break;
 
1801
                case VOXEL_REPRESENT_ISOSURF:
 
1802
                        return std::string("Isosurface");
 
1803
                        break;
 
1804
                default:
 
1805
                        return "";
 
1806
                        break;
 
1807
        }
 
1808
}
 
1809
 
 
1810
void VoxeliseFilter::getProperties(FilterProperties &propertyList) const
 
1811
{
 
1812
        propertyList.data.clear();
 
1813
        propertyList.keys.clear();
 
1814
        propertyList.types.clear();
 
1815
        
 
1816
        vector<unsigned int> type,keys;
 
1817
        vector<pair<string,string> > s;
 
1818
 
 
1819
        string tmpStr;
 
1820
        stream_cast(tmpStr, fixedWidth);
 
1821
        s.push_back(std::make_pair("Fixed width", tmpStr));
 
1822
        keys.push_back(KEY_VOXEL_FIXEDWIDTH);
 
1823
        type.push_back(PROPERTY_TYPE_BOOL);
 
1824
        
 
1825
        if(fixedWidth)
 
1826
        {
 
1827
                stream_cast(tmpStr,binWidth[0]);
 
1828
                keys.push_back(KEY_VOXEL_WIDTHBINSX);
 
1829
                s.push_back(make_pair("Bin width x", tmpStr));
 
1830
                type.push_back(PROPERTY_TYPE_REAL);
 
1831
 
 
1832
                stream_cast(tmpStr,binWidth[1]);
 
1833
                keys.push_back(KEY_VOXEL_WIDTHBINSY);
 
1834
                s.push_back(make_pair("Bin width y", tmpStr));
 
1835
                type.push_back(PROPERTY_TYPE_REAL);
 
1836
 
 
1837
                stream_cast(tmpStr,binWidth[2]);
 
1838
                keys.push_back(KEY_VOXEL_WIDTHBINSZ);
 
1839
                s.push_back(make_pair("Bin width z", tmpStr));
 
1840
                type.push_back(PROPERTY_TYPE_REAL);
 
1841
        }
 
1842
        else
 
1843
        {
 
1844
                stream_cast(tmpStr,nBins[0]);
 
1845
                keys.push_back(KEY_VOXEL_NBINSX);
 
1846
                s.push_back(make_pair("Num bins x", tmpStr));
 
1847
                type.push_back(PROPERTY_TYPE_INTEGER);
 
1848
                
 
1849
                stream_cast(tmpStr,nBins[1]);
 
1850
                keys.push_back(KEY_VOXEL_NBINSY);
 
1851
                s.push_back(make_pair("Num bins y", tmpStr));
 
1852
                type.push_back(PROPERTY_TYPE_INTEGER);
 
1853
                
 
1854
                stream_cast(tmpStr,nBins[2]);
 
1855
                keys.push_back(KEY_VOXEL_NBINSZ);
 
1856
                s.push_back(make_pair("Num bins z", tmpStr));
 
1857
                type.push_back(PROPERTY_TYPE_INTEGER);
 
1858
        }
 
1859
 
 
1860
        //Let the user know what the valid values for voxel value types are
 
1861
        string tmpChoice;       
 
1862
        vector<pair<unsigned int,string> > choices;
 
1863
        tmpStr=getNormaliseTypeString(VOXEL_NORMALISETYPE_NONE);
 
1864
        choices.push_back(make_pair((unsigned int)VOXEL_NORMALISETYPE_NONE,tmpStr));
 
1865
        tmpStr=getNormaliseTypeString(VOXEL_NORMALISETYPE_VOLUME);
 
1866
        choices.push_back(make_pair((unsigned int)VOXEL_NORMALISETYPE_VOLUME,tmpStr));
 
1867
        if(rsdIncoming)
 
1868
        {
 
1869
                //Concentration mode
 
1870
                tmpStr=getNormaliseTypeString(VOXEL_NORMALISETYPE_ALLATOMSINVOXEL);
 
1871
                choices.push_back(make_pair((unsigned int)VOXEL_NORMALISETYPE_ALLATOMSINVOXEL,tmpStr));
 
1872
                //Ratio is only valid if we have a way of seperation for the ions i.e. range
 
1873
                tmpStr=getNormaliseTypeString(VOXEL_NORMALISETYPE_COUNT2INVOXEL);
 
1874
                choices.push_back(make_pair((unsigned int)VOXEL_NORMALISETYPE_COUNT2INVOXEL,tmpStr));
 
1875
        }
 
1876
        tmpStr= choiceString(choices,normaliseType);
 
1877
        s.push_back(make_pair(string("Normalise by"),tmpStr));
 
1878
        type.push_back(PROPERTY_TYPE_CHOICE);
 
1879
        keys.push_back(KEY_VOXEL_NORMALISE_TYPE);
 
1880
        
 
1881
        
 
1882
        //TODO
 
1883
        //1. range file
 
1884
        //2. threshold
 
1885
        //3. gaussian
 
1886
        
 
1887
        propertyList.data.push_back(s);
 
1888
        propertyList.types.push_back(type);
 
1889
        propertyList.keys.push_back(keys);
 
1890
 
 
1891
        s.clear();
 
1892
        type.clear();
 
1893
        keys.clear();
 
1894
 
 
1895
                
 
1896
        // numerator
 
1897
        if (rsdIncoming) {
 
1898
                s.push_back(make_pair("Numerator", numeratorAll ? "1" : "0"));
 
1899
                type.push_back(PROPERTY_TYPE_BOOL);
 
1900
                keys.push_back(KEY_VOXEL_ENABLE_NUMERATOR);
 
1901
 
 
1902
                ASSERT(rsdIncoming->enabledIons.size()==enabledIons[0].size()); 
 
1903
                ASSERT(rsdIncoming->enabledIons.size()==enabledIons[1].size()); 
 
1904
 
 
1905
                //Look at the numerator 
 
1906
                for(unsigned  int ui=0; ui<rsdIncoming->enabledIons.size(); ui++)
 
1907
                {
 
1908
                        string str;
 
1909
                        if(enabledIons[0][ui])
 
1910
                                str="1";
 
1911
                        else
 
1912
                                str="0";
 
1913
 
 
1914
                        //Append the ion name with a checkbox
 
1915
                        s.push_back(make_pair(
 
1916
                                rsdIncoming->rangeFile->getName(ui), str));
 
1917
                        type.push_back(PROPERTY_TYPE_BOOL);
 
1918
                        keys.push_back(KEY_VOXEL_ENABLE_NUMERATOR*1000+ui);
 
1919
                }
 
1920
                propertyList.types.push_back(type);
 
1921
                propertyList.data.push_back(s);
 
1922
                propertyList.keys.push_back(keys);
 
1923
        }
 
1924
        
 
1925
        s.clear();
 
1926
        type.clear();
 
1927
        keys.clear();
 
1928
        
 
1929
        if (normaliseType == VOXEL_NORMALISETYPE_COUNT2INVOXEL && rsdIncoming) {
 
1930
                // denominator
 
1931
                s.push_back(make_pair("Denominator", denominatorAll ? "1" : "0"));
 
1932
                type.push_back(PROPERTY_TYPE_BOOL);
 
1933
                keys.push_back(KEY_VOXEL_ENABLE_DENOMINATOR);
 
1934
 
 
1935
                for(unsigned  int ui=0; ui<rsdIncoming->enabledIons.size(); ui++)
 
1936
                {                       
 
1937
                        string str;
 
1938
                        if(enabledIons[1][ui])
 
1939
                                str="1";
 
1940
                        else
 
1941
                                str="0";
 
1942
 
 
1943
                        //Append the ion name with a checkbox
 
1944
                        s.push_back(make_pair(
 
1945
                                rsdIncoming->rangeFile->getName(ui), str));
 
1946
 
 
1947
                        type.push_back(PROPERTY_TYPE_BOOL);
 
1948
                        keys.push_back(KEY_VOXEL_ENABLE_DENOMINATOR*1000+ui);
 
1949
                }
 
1950
                propertyList.types.push_back(type);
 
1951
                propertyList.data.push_back(s);
 
1952
                propertyList.keys.push_back(keys);
 
1953
 
 
1954
                s.clear();
 
1955
                type.clear();
 
1956
                keys.clear();
 
1957
        }
 
1958
        
 
1959
        //start a new set for the visual representation
 
1960
        //----------------------------
 
1961
        choices.clear();
 
1962
        tmpStr=getRepresentTypeString(VOXEL_REPRESENT_POINTCLOUD);
 
1963
        choices.push_back(make_pair((unsigned int)VOXEL_REPRESENT_POINTCLOUD,tmpStr));
 
1964
        tmpStr=getRepresentTypeString(VOXEL_REPRESENT_ISOSURF);
 
1965
        choices.push_back(make_pair((unsigned int)VOXEL_REPRESENT_ISOSURF,tmpStr));
 
1966
        
 
1967
        
 
1968
        tmpStr= choiceString(choices,representation);
 
1969
        s.push_back(make_pair(string("Representation"),tmpStr));
 
1970
        type.push_back(PROPERTY_TYPE_CHOICE);
 
1971
        keys.push_back(KEY_VOXEL_REPRESENTATION_MODE);
 
1972
        switch(representation)
 
1973
        {
 
1974
                case VOXEL_REPRESENT_POINTCLOUD:
 
1975
                {
 
1976
                        stream_cast(tmpStr,splatSize);
 
1977
                        s.push_back(make_pair("Spot size",tmpStr));
 
1978
                        type.push_back(PROPERTY_TYPE_REAL);
 
1979
                        keys.push_back(KEY_VOXEL_SPOTSIZE);
 
1980
 
 
1981
                        stream_cast(tmpStr,1.0-a);
 
1982
                        s.push_back(make_pair("Transparency",tmpStr));
 
1983
                        type.push_back(PROPERTY_TYPE_REAL);
 
1984
                        keys.push_back(KEY_VOXEL_TRANSPARANCY);
 
1985
                        break;
 
1986
                }
 
1987
                case VOXEL_REPRESENT_ISOSURF:
 
1988
                {
 
1989
                        stream_cast(tmpStr,isoLevel);
 
1990
                        s.push_back(make_pair("Isovalue",tmpStr));
 
1991
                        type.push_back(PROPERTY_TYPE_REAL);
 
1992
                        keys.push_back(KEY_VOXEL_ISOLEVEL);
 
1993
                
 
1994
                                
 
1995
 
 
1996
                        //Convert the ion colour to a hex string        
 
1997
                        genColString((unsigned char)(r*255),(unsigned char)(g*255),
 
1998
                                        (unsigned char)(b*255),(unsigned char)(a*255),tmpStr);
 
1999
                        s.push_back(make_pair("Colour",tmpStr));
 
2000
                        type.push_back(PROPERTY_TYPE_COLOUR);
 
2001
                        keys.push_back(KEY_VOXEL_COLOUR);
 
2002
                        
 
2003
                        break;
 
2004
                }
 
2005
                default:
 
2006
                        ASSERT(false);
 
2007
                        ;
 
2008
        }
 
2009
        
 
2010
        //----------------------------
 
2011
        
 
2012
        propertyList.data.push_back(s);
 
2013
        propertyList.types.push_back(type);
 
2014
        propertyList.keys.push_back(keys);
 
2015
}
 
2016
 
 
2017
bool VoxeliseFilter::setProperty( unsigned int set, unsigned int key,
 
2018
                                                                          const std::string &value, bool &needUpdate)
 
2019
{
 
2020
        
 
2021
        needUpdate=false;
 
2022
        switch(key)
 
2023
        {
 
2024
                case KEY_VOXEL_FIXEDWIDTH: 
 
2025
                {
 
2026
                        bool b;
 
2027
                        if(stream_cast(b,value))
 
2028
                                return false;
 
2029
                        fixedWidth=b;
 
2030
                        needUpdate=true;                        
 
2031
                        break;
 
2032
                }       
 
2033
                case KEY_VOXEL_NBINSX:
 
2034
                {
 
2035
                        int i;
 
2036
                        if(stream_cast(i,value))
 
2037
                                return false;
 
2038
                        if(i <= 0)
 
2039
                                return false;
 
2040
                        needUpdate=true;
 
2041
                        nBins[0]=i;
 
2042
                        calculateWidthsFromNumBins(binWidth, nBins);
 
2043
                        break;
 
2044
                }
 
2045
                case KEY_VOXEL_NBINSY:
 
2046
                {
 
2047
                        int i;
 
2048
                        if(stream_cast(i,value))
 
2049
                                return false;
 
2050
                        if(i <= 0)
 
2051
                                return false;
 
2052
                        needUpdate=true;
 
2053
                        nBins[1]=i;
 
2054
                        calculateWidthsFromNumBins(binWidth, nBins);
 
2055
                        break;
 
2056
                }
 
2057
                case KEY_VOXEL_NBINSZ:
 
2058
                {
 
2059
                        int i;
 
2060
                        if(stream_cast(i,value))
 
2061
                                return false;
 
2062
                        if(i <= 0)
 
2063
                                return false;
 
2064
                        needUpdate=true;
 
2065
                        nBins[2]=i;
 
2066
                        calculateWidthsFromNumBins(binWidth, nBins);
 
2067
                        break;
 
2068
                }
 
2069
                case KEY_VOXEL_WIDTHBINSX:
 
2070
                {
 
2071
                        float f;
 
2072
                        if(stream_cast(f,value))
 
2073
                                return false;
 
2074
                        if(f <= 0.0f)
 
2075
                                return false;
 
2076
                        needUpdate=true;
 
2077
                        binWidth[0]=f;
 
2078
                        calculateNumBinsFromWidths(binWidth, nBins);
 
2079
                        break;
 
2080
                }
 
2081
                case KEY_VOXEL_WIDTHBINSY:
 
2082
                {
 
2083
                        float f;
 
2084
                        if(stream_cast(f,value))
 
2085
                                return false;
 
2086
                        if(f <= 0.0f)
 
2087
                                return false;
 
2088
                        needUpdate=true;
 
2089
                        binWidth[1]=f;
 
2090
                        calculateNumBinsFromWidths(binWidth, nBins);
 
2091
                        break;
 
2092
                }
 
2093
                case KEY_VOXEL_WIDTHBINSZ:
 
2094
                {
 
2095
                        float f;
 
2096
                        if(stream_cast(f,value))
 
2097
                                return false;
 
2098
                        if(f <= 0.0f)
 
2099
                                return false;
 
2100
                        needUpdate=true;
 
2101
                        binWidth[2]=f;
 
2102
                        calculateNumBinsFromWidths(binWidth, nBins);
 
2103
                        break;
 
2104
                }
 
2105
                case KEY_VOXEL_NORMALISE_TYPE:
 
2106
                {
 
2107
                        int i;
 
2108
                        for (i = 0; i < VOXEL_NORMALISETYPE_MAX; i++)
 
2109
                                if (value == getNormaliseTypeString(i)) break;
 
2110
                        if (i == VOXEL_NORMALISETYPE_MAX)
 
2111
                                return false;
 
2112
                        if(normaliseType!=i)
 
2113
                                needUpdate=true;
 
2114
                        normaliseType=i;
 
2115
                        break;
 
2116
                }
 
2117
                case KEY_VOXEL_SPOTSIZE:
 
2118
                {
 
2119
                        float f;
 
2120
                        if(stream_cast(f,value))
 
2121
                                return false;
 
2122
                        if(f <= 0.0f)
 
2123
                                return false;
 
2124
                        needUpdate=true;
 
2125
                        splatSize=f;
 
2126
                        break;
 
2127
                }
 
2128
                case KEY_VOXEL_TRANSPARANCY:
 
2129
                {
 
2130
                        float f;
 
2131
                        if(stream_cast(f,value))
 
2132
                                return false;
 
2133
                        if(f <= 0.0f || f > 1.0)
 
2134
                                return false;
 
2135
                        needUpdate=true;
 
2136
                        //Alpha is opacity, which is 1-transparancy
 
2137
                        a=1.0f-f;
 
2138
                        break;
 
2139
                }
 
2140
                case KEY_VOXEL_ISOLEVEL:
 
2141
                {
 
2142
                        float f;
 
2143
                        if(stream_cast(f,value))
 
2144
                                return false;
 
2145
                        if(f <= 0.0f)
 
2146
                                return false;
 
2147
                        needUpdate=true;
 
2148
                        isoLevel=f;
 
2149
                        break;
 
2150
                }
 
2151
                case KEY_VOXEL_COLOUR:
 
2152
                {
 
2153
                        unsigned char newR,newG,newB,newA;
 
2154
 
 
2155
                        parseColString(value,newR,newG,newB,newA);
 
2156
 
 
2157
                        if(newB != b || newR != r ||
 
2158
                                newG !=g || newA != a)
 
2159
                                needUpdate=true;
 
2160
                        r=newR/255.0;
 
2161
                        g=newG/255.0;
 
2162
                        b=newB/255.0;
 
2163
                        break;
 
2164
                }
 
2165
                case KEY_VOXEL_REPRESENTATION_MODE:
 
2166
                {
 
2167
                        int i;
 
2168
                        for (i = 0; i < VOXEL_REPRESENT_END; i++)
 
2169
                                if (value == getRepresentTypeString(i)) break;
 
2170
                        if (i == VOXEL_REPRESENT_END)
 
2171
                                return false;
 
2172
                        needUpdate=true;
 
2173
                        representation=i;
 
2174
                        break;
 
2175
                }
 
2176
                case KEY_VOXEL_ENABLE_NUMERATOR:
 
2177
                {
 
2178
                        bool b;
 
2179
                        if(stream_cast(b,value))
 
2180
                                return false;
 
2181
                        //Set them all to enabled or disabled as a group        
 
2182
                        for (size_t i = 0; i < enabledIons[0].size(); i++) 
 
2183
                                enabledIons[0][i] = b;
 
2184
                        numeratorAll = b;
 
2185
                        needUpdate=true;                        
 
2186
                        break;
 
2187
                }
 
2188
                case KEY_VOXEL_ENABLE_DENOMINATOR:
 
2189
                {
 
2190
                        bool b;
 
2191
                        if(stream_cast(b,value))
 
2192
                                return false;
 
2193
        
 
2194
                        //Set them all to enabled or disabled as a group        
 
2195
                        for (size_t i = 0; i < enabledIons[1].size(); i++) 
 
2196
                                enabledIons[1][i] = b;
 
2197
                        
 
2198
                        denominatorAll = b;
 
2199
                        needUpdate=true;                        
 
2200
                        break;
 
2201
                }
 
2202
                default:
 
2203
                {
 
2204
                        if (key >= KEY_VOXEL_ENABLE_DENOMINATOR*1000) {
 
2205
                                bool b;
 
2206
                                if(stream_cast(b,value))
 
2207
                                        return false;
 
2208
//                              if (b && !rsdIncoming->enabledIons[key - KEY_VOXEL_ENABLE_DENOMINATOR*1000]) {
 
2209
//                                      return false;
 
2210
//                              }
 
2211
                                enabledIons[1][key - KEY_VOXEL_ENABLE_DENOMINATOR*1000]=b;
 
2212
                                if (!b) {
 
2213
                                        denominatorAll = false;
 
2214
                                }
 
2215
                                needUpdate=true;                        
 
2216
                        } else if (key >= KEY_VOXEL_ENABLE_NUMERATOR*1000) {
 
2217
                                bool b;
 
2218
                                if(stream_cast(b,value))
 
2219
                                        return false;
 
2220
//                              if (b && !rsdIncoming->enabledIons[key - KEY_VOXEL_ENABLE_NUMERATOR*1000]) {
 
2221
//                                      return false;
 
2222
//                              }
 
2223
                                enabledIons[0][key - KEY_VOXEL_ENABLE_NUMERATOR*1000]=b;
 
2224
                                if (!b) {
 
2225
                                        numeratorAll = false;
 
2226
                                }
 
2227
                                needUpdate=true;                        
 
2228
                        }
 
2229
                        else
 
2230
                        {
 
2231
                                ASSERT(false);
 
2232
                        }
 
2233
                        break;
 
2234
                }
 
2235
        }
 
2236
        return true;
 
2237
}
 
2238
 
 
2239
std::string  VoxeliseFilter::getErrString(unsigned int code) const
 
2240
{
 
2241
        switch(code)
 
2242
        {
 
2243
                case VOXEL_ABORT_ERR:
 
2244
                {
 
2245
                        return std::string("Voxelisation aborted");
 
2246
                }
 
2247
                case VOXEL_BOUNDS_INVALID_ERR:
 
2248
                {
 
2249
                        return std::string("Voxelisation bounds are invalid");
 
2250
                }
 
2251
        }       
 
2252
        
 
2253
        return std::string("BUG! Should not see this (VoxeliseFilter)");
 
2254
}
 
2255
 
 
2256
bool VoxeliseFilter::writeState(std::ofstream &f,unsigned int format, unsigned int depth) const
 
2257
{
 
2258
        using std::endl;
 
2259
        switch(format)
 
2260
        {
 
2261
                case STATE_FORMAT_XML:
 
2262
                {       
 
2263
                        f << tabs(depth) << "<voxelise>" << endl;
 
2264
                        f << tabs(depth+1) << "<fixedWidth value=\""<<fixedWidth << "\"/>"  << endl;
 
2265
                        f << tabs(depth+1) << "<nBins values=\""<<nBins[0] << ","<<nBins[1]<<","<<nBins[2] << "\"/>"  << endl;
 
2266
                        f << tabs(depth+1) << "<binWidth values=\""<<binWidth[0] << ","<<binWidth[1]<<","<<binWidth[2] << "\"/>"  << endl;
 
2267
                        f << tabs(depth+1) << "<normaliseType value=\""<<normaliseType << "\"/>"  << endl;
 
2268
                        f << tabs(depth+1) << "<representation value=\""<<representation << "\"/>" << endl;
 
2269
                        f << tabs(depth+1) << "<colour r=\"" <<  r<< "\" g=\"" << g << "\" b=\"" <<b
 
2270
                                << "\" a=\"" << a << "\"/>" <<endl;
 
2271
                        f << tabs(depth) << "</voxelise>" << endl;
 
2272
                        break;
 
2273
                }
 
2274
                default:
 
2275
                        ASSERT(false);
 
2276
                        return false;
 
2277
        }
 
2278
        
 
2279
        return true;
 
2280
}
 
2281
 
 
2282
bool VoxeliseFilter::readState(xmlNodePtr &nodePtr)
 
2283
{
 
2284
        using std::string;
 
2285
        string tmpStr;
 
2286
        xmlChar *xmlString;
 
2287
        
 
2288
        //Retrieve fixedWidth mode
 
2289
        if(XMLHelpFwdToElem(nodePtr,"fixedWidth"))
 
2290
                return false;
 
2291
        
 
2292
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"value");
 
2293
        if(!xmlString)
 
2294
                return false;
 
2295
        
 
2296
        tmpStr=(char *)xmlString;
 
2297
        if(tmpStr == "1") 
 
2298
                fixedWidth=true;
 
2299
        else if(tmpStr== "0")
 
2300
                fixedWidth=false;
 
2301
        else
 
2302
        {
 
2303
                xmlFree(xmlString);
 
2304
                return false;
 
2305
        }
 
2306
        
 
2307
        xmlFree(xmlString);     
 
2308
        
 
2309
        //Retrieve nBins        
 
2310
        if(XMLHelpFwdToElem(nodePtr,"nBins"))
 
2311
                return false;
 
2312
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"values");
 
2313
        if(!xmlString)
 
2314
                return false;
 
2315
        std::vector<string> v1;
 
2316
        splitStrsRef((char *)xmlString,',',v1);
 
2317
        for (size_t i = 0; i < INDEX_LENGTH && i < v1.size(); i++)
 
2318
        {
 
2319
                if(stream_cast(nBins[i],v1[i]))
 
2320
                        return false;
 
2321
                
 
2322
                if(nBins[i] <= 0)
 
2323
                        return false;
 
2324
        }
 
2325
        xmlFree(xmlString);
 
2326
        
 
2327
        //Retrieve nBins        
 
2328
        if(XMLHelpFwdToElem(nodePtr,"binWidth"))
 
2329
                return false;
 
2330
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"values");
 
2331
        if(!xmlString)
 
2332
                return false;
 
2333
        std::vector<string> v2;
 
2334
        splitStrsRef((char *)xmlString,',',v2);
 
2335
        for (size_t i = 0; i < INDEX_LENGTH && i < v2.size(); i++)
 
2336
        {
 
2337
                if(stream_cast(binWidth[i],v2[i]))
 
2338
                        return false;
 
2339
                
 
2340
                if(binWidth[i] <= 0)
 
2341
                        return false;
 
2342
        }
 
2343
        xmlFree(xmlString);
 
2344
        
 
2345
        //Retrieve normaliseType
 
2346
        if(XMLHelpFwdToElem(nodePtr,"normaliseType"))
 
2347
                return false;
 
2348
        
 
2349
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"value");
 
2350
        if(!xmlString)
 
2351
                return false;
 
2352
        tmpStr=(char *)xmlString;
 
2353
        
 
2354
        if(stream_cast(normaliseType,tmpStr))
 
2355
                return false;
 
2356
        
 
2357
        xmlFree(xmlString);     
 
2358
        
 
2359
        //Retrieve representation
 
2360
        if(XMLHelpFwdToElem(nodePtr,"representation"))
 
2361
                return false;
 
2362
        
 
2363
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"value");
 
2364
        if(!xmlString)
 
2365
                return false;
 
2366
        tmpStr=(char *)xmlString;
 
2367
        
 
2368
        if(stream_cast(representation,tmpStr))
 
2369
                return false;
 
2370
        xmlFree(xmlString);     
 
2371
 
 
2372
        if(representation >=VOXEL_REPRESENT_END)
 
2373
                return false;
 
2374
 
 
2375
 
 
2376
        //Retrieve colour
 
2377
        //====
 
2378
        if(XMLHelpFwdToElem(nodePtr,"colour"))
 
2379
                return false;
 
2380
        
 
2381
        //--red--
 
2382
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"r");
 
2383
        if(!xmlString)
 
2384
                return false;
 
2385
        tmpStr=(char *)xmlString;
 
2386
 
 
2387
        //convert from string to digit
 
2388
        if(stream_cast(r,tmpStr))
 
2389
                return false;
 
2390
 
 
2391
        //disallow negative or values gt 1.
 
2392
        if(r < 0.0f || r > 1.0f)
 
2393
                return false;
 
2394
 
 
2395
        //--green--
 
2396
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"g");
 
2397
        if(!xmlString)
 
2398
                return false;
 
2399
        tmpStr=(char *)xmlString;
 
2400
 
 
2401
        //convert from string to digit
 
2402
        if(stream_cast(g,tmpStr))
 
2403
                return false;
 
2404
 
 
2405
        //disallow negative or values gt 1.
 
2406
        if(g < 0.0f || g > 1.0f)
 
2407
                return false;
 
2408
 
 
2409
        //--blue--
 
2410
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"b");
 
2411
        if(!xmlString)
 
2412
                return false;
 
2413
        tmpStr=(char *)xmlString;
 
2414
 
 
2415
        //convert from string to digit
 
2416
        if(stream_cast(b,tmpStr))
 
2417
                return false;
 
2418
 
 
2419
        //disallow negative or values gt 1.
 
2420
        if(b < 0.0f || b > 1.0f)
 
2421
                return false;
 
2422
 
 
2423
        //--Alpha--
 
2424
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"a");
 
2425
        if(!xmlString)
 
2426
                return false;
 
2427
        tmpStr=(char *)xmlString;
 
2428
 
 
2429
        //convert from string to digit
 
2430
        if(stream_cast(a,tmpStr))
 
2431
                return false;
 
2432
 
 
2433
        //disallow negative or values gt 1.
 
2434
        if(a < 0.0f || a > 1.0f)
 
2435
                return false;
 
2436
        //====
 
2437
        return true;
 
2438
        
 
2439
}
 
2440
 
 
2441
//TODO
 
2442
void VoxeliseFilter::setPropFromBinding(const SelectionBinding &b)
 
2443
{
 
2444
}       
 
2445
 
1219
2446
//== Range File Filter == 
1220
2447
 
1221
2448
RangeFileFilter::RangeFileFilter()
1243
2470
        //not the cache itself
1244
2471
        p->cache=cache;
1245
2472
        p->cacheOK=false;
1246
 
        p->enabled=enabled;
1247
2473
        p->progress=progress;
1248
2474
        p->userString=userString;       
1249
2475
        return p;
1250
2476
}
1251
2477
 
 
2478
void RangeFileFilter::initFilter(const std::vector<const FilterStreamData *> &dataIn,
 
2479
                                std::vector<const FilterStreamData *> &dataOut)
 
2480
{
 
2481
        //Copy any input, except range files to output
 
2482
        for(size_t ui=0;ui<dataIn.size();ui++)
 
2483
        {
 
2484
                if(dataIn[ui]->getStreamType() != STREAM_TYPE_RANGE)
 
2485
                        dataOut.push_back(dataIn[ui]);
 
2486
        }
 
2487
 
 
2488
        //Create a rangestream data to push through the init phase
 
2489
        if(rng.getNumIons() && rng.getNumRanges())
 
2490
        {
 
2491
                RangeStreamData *rngData=new RangeStreamData;
 
2492
                rngData->rangeFile=&rng;        
 
2493
                rngData->enabledRanges.resize(enabledRanges.size());    
 
2494
                std::copy(enabledRanges.begin(),enabledRanges.end(),rngData->enabledRanges.begin());
 
2495
                rngData->enabledIons.resize(enabledIons.size());        
 
2496
                std::copy(enabledIons.begin(),enabledIons.end(),rngData->enabledIons.begin());
 
2497
                rngData->cached=false;
 
2498
 
 
2499
                dataOut.push_back(rngData);
 
2500
        }
 
2501
        
 
2502
}
 
2503
 
1252
2504
unsigned int RangeFileFilter::refresh(const std::vector<const FilterStreamData *> &dataIn,
1253
2505
                std::vector<const FilterStreamData *> &getOut, unsigned int &progress, bool (*callback)(void))
1254
2506
{
1290
2542
        haveIonSize=false;
1291
2543
        sameSize=true;
1292
2544
 
 
2545
 
1293
2546
        vector<size_t> dSizes;
1294
2547
        dSizes.resize(d.size(),0);
1295
 
 
1296
2548
        //Do a first sweep to obtain range sizes needed
1297
2549
        for(unsigned int ui=0;ui<dataIn.size() ;ui++)
1298
2550
        {
1300
2552
                {
1301
2553
                        case STREAM_TYPE_IONS: 
1302
2554
                        {
1303
 
                                for(vector<IonHit>::const_iterator it=((const IonStreamData *)dataIn[ui])->data.begin();
1304
 
                                               it!=((const IonStreamData *)dataIn[ui])->data.end(); it++)
 
2555
 
 
2556
#ifdef _OPENMP
 
2557
                                //Create a unique array for each thread, so they don't try
 
2558
                                //to modify the same data structure
 
2559
                                unsigned int nT =omp_get_max_threads(); 
 
2560
                                vector<size_t> *dSizeArr = new vector<size_t>[nT];
 
2561
                                for(unsigned int uk=0;uk<nT;uk++)
 
2562
                                        dSizeArr[uk].resize(dSizes.size(),0);
 
2563
#endif
 
2564
                                const IonStreamData *src = ((const IonStreamData *)dataIn[ui]);
 
2565
                                #pragma omp parallel for
 
2566
                                for(size_t uj=0; uj<src->data.size();uj++)
1305
2567
                                {
 
2568
#ifdef _OPENMP
 
2569
                                        unsigned int thisT=omp_get_thread_num();
 
2570
#endif
1306
2571
                                        unsigned int rangeID;
1307
 
                                        rangeID=rng.getRangeID(it->getMassToCharge());
 
2572
                                        rangeID=rng.getRangeID(src->data[uj].getMassToCharge());
1308
2573
 
1309
2574
                                        //If ion is unranged, then it will have a rangeID of -1
1310
2575
                                        if(rangeID != (unsigned int)-1 && enabledRanges[rangeID] )
1312
2577
                                                unsigned int ionID=rng.getIonID(rangeID);
1313
2578
 
1314
2579
                                                if(enabledIons[ionID])
1315
 
                                                        dSizes[ionID]++;
 
2580
                                                {
 
2581
                                                        #ifdef _OPENMP
 
2582
                                                                dSizeArr[thisT][ionID]++;
 
2583
                                                        #else
 
2584
                                                                dSizes[ionID]++;
 
2585
                                                        #endif
 
2586
 
 
2587
                                                }
1316
2588
                                        }
1317
2589
                                }
 
2590
#ifdef _OPENMP
 
2591
                                //Merge the arrays back together
 
2592
                                for(unsigned int uk=0;uk<nT;uk++)
 
2593
                                {
 
2594
                                        for(unsigned int uj=0;uj<dSizes.size();uj++)
 
2595
                                                dSizes[uj] = dSizes[uj]+dSizeArr[uk][uj];
 
2596
                                }
 
2597
#endif
1318
2598
 
1319
2599
                        }
1320
2600
                }
1348
2628
                                //the first input ion colour.
1349
2629
                                if(!haveDefIonColour)
1350
2630
                                {
1351
 
                                        //FIXME: This could be handled better by 
1352
 
                                        //assigning an "unranged" colour.
1353
 
                                        //particularly in the case where we have
1354
 
                                        //multiple input streams (think re-ranging)
1355
2631
                                        defIonColour.red =  ((IonStreamData *)dataIn[ui])->r;
1356
2632
                                        defIonColour.green =  ((IonStreamData *)dataIn[ui])->g;
1357
2633
                                        defIonColour.blue =  ((IonStreamData *)dataIn[ui])->b;
1462
2738
                        d[ui]->cached=1; //IMPORTANT: ->cached must be set PRIOR to push back
1463
2739
                        filterOutputs.push_back(d[ui]);
1464
2740
                }
1465
 
                cacheOK=true;
1466
2741
        }
1467
2742
        else
1468
2743
        {
1469
2744
                for(unsigned int ui=0;ui<d.size(); ui++)
1470
2745
                        d[ui]->cached=0; //IMPORTANT: ->cached must be set PRIOR to push back
 
2746
                cacheOK=false;
1471
2747
        }
1472
2748
        
1473
2749
        for(unsigned int ui=0;ui<d.size(); ui++)
1476
2752
        //Put out rangeData
1477
2753
        RangeStreamData *rngData=new RangeStreamData;
1478
2754
        rngData->rangeFile=&rng;        
1479
 
        rngData->enabledRanges=&enabledRanges;  
1480
 
        rngData->enabledIons=&enabledIons;      
 
2755
        
 
2756
        rngData->enabledRanges.resize(enabledRanges.size());    
 
2757
        std::copy(enabledRanges.begin(),enabledRanges.end(),rngData->enabledRanges.begin());
 
2758
        rngData->enabledIons.resize(enabledIons.size());        
 
2759
        std::copy(enabledIons.begin(),enabledIons.end(),rngData->enabledIons.begin());
 
2760
        
1481
2761
        
1482
2762
        rngData->cached=cache;
 
2763
        
 
2764
        if(cache)
 
2765
                filterOutputs.push_back(rngData);
 
2766
 
1483
2767
        getOut.push_back(rngData);
1484
2768
                
 
2769
        cacheOK=cache;
1485
2770
        return 0;
1486
2771
}
1487
2772
 
 
2773
void RangeFileFilter::guessFormat(const std::string &s)
 
2774
{
 
2775
        vector<string> sVec;
 
2776
        splitStrsRef(s.c_str(),'.',sVec);
 
2777
 
 
2778
        if(!sVec.size())
 
2779
                assumedFileFormat=RANGE_FORMAT_ORNL;
 
2780
        else if(lowercase(sVec[sVec.size()-1]) == "rrng")
 
2781
                assumedFileFormat=RANGE_FORMAT_RRNG;
 
2782
        else if(lowercase(sVec[sVec.size()-1]) == "env")
 
2783
                assumedFileFormat=RANGE_FORMAT_ENV;
 
2784
        else
 
2785
                assumedFileFormat=RANGE_FORMAT_ORNL;
 
2786
}
 
2787
 
1488
2788
unsigned int RangeFileFilter::updateRng()
1489
2789
{
1490
2790
        unsigned int uiErr;     
1912
3212
                        f << tabs(depth+1) << "<enabledions>"<< endl;
1913
3213
                        for(unsigned int ui=0;ui<enabledIons.size();ui++)
1914
3214
                        {
 
3215
                                RGB col;
 
3216
                                string colourString;
 
3217
                                col = rng.getColour(ui);
 
3218
 
 
3219
                                genColString((unsigned char)(col.red*255),(unsigned char)(col.green*255),
 
3220
                                                (unsigned char)(col.blue*255),255,colourString);
1915
3221
                                f<< tabs(depth+2) << "<ion id=\"" << ui << "\" enabled=\"" 
1916
 
                                        << (int)enabledIons[ui] << "\"/>" << endl;
 
3222
                                        << (int)enabledIons[ui] << "\" colour=\"" << colourString << "\"/>" << endl;
1917
3223
                        }
1918
3224
                        f << tabs(depth+1) << "</enabledions>"<< endl;
1919
3225
 
1962
3268
        rngName=(char *)xmlString;
1963
3269
        xmlFree(xmlString);
1964
3270
 
1965
 
        //Load range file
 
3271
        //try using the extention name of the file to guess format
 
3272
        guessFormat(rngName);
 
3273
 
 
3274
        //Load range file using guessed format
1966
3275
        if(rng.open(rngName.c_str(),assumedFileFormat))
1967
 
                return false;
1968
 
        
 
3276
        {
 
3277
                //If that failed, go to plan B
 
3278
                //Brute force try all readers
 
3279
                bool openOK=false;
 
3280
 
 
3281
                for(unsigned int ui=1;ui<RANGE_FORMAT_END_OF_ENUM; ui++)
 
3282
                {
 
3283
                        if(!rng.open(rngName.c_str(),ui))
 
3284
                        {
 
3285
                                assumedFileFormat=ui;
 
3286
                                openOK=true;
 
3287
                                break;
 
3288
                        }
 
3289
                }
 
3290
        
 
3291
                if(!openOK)
 
3292
                        return false;
 
3293
        }
 
3294
        
 
3295
 
 
3296
 
 
3297
                
1969
3298
        //==
1970
3299
        
1971
3300
        std::string tmpStr;
2030
3359
                else
2031
3360
                        return false;
2032
3361
 
2033
 
                xmlFree(xmlString);
2034
3362
                enabledIons[ionID]=enabled;
 
3363
                xmlFree(xmlString);
 
3364
                
 
3365
                
 
3366
                xmlString=xmlGetProp(nodePtr,(const xmlChar *)"colour");
 
3367
                if(!xmlString)
 
3368
                        return false;
 
3369
 
 
3370
 
 
3371
                tmpStr=(char *)xmlString;
 
3372
 
 
3373
                unsigned char r,g,b,a;
 
3374
                if(!parseColString(tmpStr,r,g,b,a))
 
3375
                        return false;
 
3376
                
 
3377
                RGB col;
 
3378
                col.red=(float)r/255.0f;
 
3379
                col.green=(float)g/255.0f;
 
3380
                col.blue=(float)b/255.0f;
 
3381
                rng.setColour(ionID,col);       
 
3382
                xmlFree(xmlString);
2035
3383
        }
2036
3384
 
2037
3385
        //===
2092
3440
        autoExtrema=true;       
2093
3441
        binWidth=0.5;
2094
3442
        plotType=0;
2095
 
        logarithmic=0;
 
3443
        logarithmic=1;
2096
3444
 
2097
3445
        //Default to blue plot
2098
3446
        r=g=0;
2118
3466
        //not the cache itself
2119
3467
        p->cache=cache;
2120
3468
        p->cacheOK=false;
2121
 
        p->enabled=enabled;
2122
3469
        p->progress=progress;
2123
3470
        p->userString=userString;
2124
3471
        return p;
2295
3642
                                        ionId=rangeD->rangeFile->getIonID(uj);
2296
3643
                                        //Only append the region if both the range
2297
3644
                                        //and the ion are enabled
2298
 
                                        if((*(rangeD->enabledRanges))[uj] && 
2299
 
                                                (*(rangeD->enabledIons))[ionId])
 
3645
                                        if((rangeD->enabledRanges)[uj] && 
 
3646
                                                (rangeD->enabledIons)[ionId])
2300
3647
                                        {
2301
3648
                                                //save the range as a "region"
2302
3649
                                                d->regions.push_back(rangeD->rangeFile->getRange(uj));
2317
3664
                }
2318
3665
        }
2319
3666
 
2320
 
#pragma omp paralell for
 
3667
#pragma omp parallel for
2321
3668
        for(unsigned int ui=0;ui<nBins;ui++)
2322
3669
        {
2323
3670
                d->xyData[ui].first = minPlot + ui*binWidth;
2340
3687
 
2341
3688
 
2342
3689
 
 
3690
                                //Sum the data bins as needed
2343
3691
                                for(unsigned int uj=0;uj<ions->data.size(); uj++)
2344
3692
                                {
2345
3693
                                        unsigned int bin;
2396
3744
 
2397
3745
        string str;
2398
3746
 
2399
 
        stream_cast(str,enabled);
2400
 
        s.push_back(std::make_pair("Enabled", str));
2401
 
        keys.push_back(KEY_SPECTRUM_ENABLED);
2402
 
        type.push_back(PROPERTY_TYPE_BOOL);
2403
 
 
2404
3747
        stream_cast(str,binWidth);
2405
3748
        keys.push_back(KEY_SPECTRUM_BINWIDTH);
2406
3749
        s.push_back(make_pair("bin width", str));
2478
3821
        needUpdate=false;
2479
3822
        switch(key)
2480
3823
        {
2481
 
                case KEY_SPECTRUM_ENABLED:
2482
 
                {
2483
 
                        string stripped=stripWhite(value);
2484
 
 
2485
 
                        if(!(stripped == "1"|| stripped == "0"))
2486
 
                                return false;
2487
 
 
2488
 
                        bool lastVal=enabled;
2489
 
                        if(stripped=="1")
2490
 
                                enabled=true;
2491
 
                        else
2492
 
                                enabled=false;
2493
 
 
2494
 
                        //if the result is different, the
2495
 
                        //cache should be invalidated
2496
 
                        if(lastVal!=enabled)
2497
 
                        {
2498
 
                                needUpdate=true;
2499
 
                                clearCache();
2500
 
                        }
2501
 
 
2502
 
                        break;
2503
 
 
2504
 
                }
2505
3824
                //Bin width
2506
3825
                case KEY_SPECTRUM_BINWIDTH:
2507
3826
                {
2905
4224
        //not the cache itself
2906
4225
        p->cache=cache;
2907
4226
        p->cacheOK=false;
2908
 
        p->enabled=enabled;
2909
4227
        p->progress=progress;
2910
4228
        p->userString=userString;
2911
4229
 
3370
4688
        string tmpChoice,tmpStr;
3371
4689
 
3372
4690
 
3373
 
        stream_cast(tmpStr,enabled);
3374
 
        s.push_back(std::make_pair("Enabled", tmpStr));
3375
 
        keys.push_back(KEY_IONCLIP_ENABLED);
3376
 
        type.push_back(PROPERTY_TYPE_BOOL);
3377
 
 
3378
4691
        vector<pair<unsigned int,string> > choices;
3379
4692
 
3380
4693
        choices.push_back(make_pair((unsigned int)PRIMITIVE_SPHERE ,
3476
4789
 
3477
4790
        switch(key)
3478
4791
        {
3479
 
                case KEY_IONCLIP_ENABLED:
3480
 
                {
3481
 
                        string stripped=stripWhite(value);
3482
 
 
3483
 
                        if(!(stripped == "1"|| stripped == "0"))
3484
 
                                return false;
3485
 
 
3486
 
                        bool lastVal=enabled;
3487
 
                        if(stripped=="1")
3488
 
                                enabled=true;
3489
 
                        else
3490
 
                                enabled=false;
3491
 
 
3492
 
                        //if the result is different, the
3493
 
                        //cache should be invalidated
3494
 
                        if(lastVal!=enabled)
3495
 
                        {
3496
 
                                needUpdate=true;
3497
 
                                clearCache();
3498
 
                        }
3499
 
 
3500
 
                        break;
3501
 
 
3502
 
                }
3503
4792
                case KEY_IONCLIP_PRIMITIVE_TYPE:
3504
4793
                {
3505
4794
                        unsigned int newPrimitive;
3623
4912
                }
3624
4913
                default:
3625
4914
                        ASSERT(false);
 
4915
                        return false;
3626
4916
        }
3627
4917
        
3628
4918
 
3629
 
        return false;
 
4919
        return true;
3630
4920
}
3631
4921
 
3632
4922
//!Get the human readable error string associated with a particular error code during refresh(...)
3908
5198
        //not the cache itself
3909
5199
        p->cache=cache;
3910
5200
        p->cacheOK=false;
3911
 
        p->enabled=enabled;
3912
5201
        p->progress=progress;
3913
5202
        p->userString=userString;
3914
5203
        return p;
3948
5237
                d[ui]=new IonStreamData;
3949
5238
                float value;
3950
5239
                value = (float)ui*(mapBounds[1]-mapBounds[0])/(float)nColours + mapBounds[0];
3951
 
                //Select the desired colour map
3952
 
                switch(colourMap)
3953
 
                {
3954
 
                        case  0:
3955
 
                                jetColorMap(rgb, value, mapBounds[0], mapBounds[1]);
3956
 
                                break;
3957
 
                        case  1:
3958
 
                                hotColorMap(rgb, value, mapBounds[0], mapBounds[1]);
3959
 
                                break;
3960
 
                        case  2:
3961
 
                                coldColorMap(rgb, value, mapBounds[0], mapBounds[1]);
3962
 
                                break;
3963
 
                        case  3:
3964
 
                                 grayColorMap(rgb, value, mapBounds[0], mapBounds[1]);
3965
 
                                break;
3966
 
                        case  4:
3967
 
                                cyclicColorMap(rgb, value, mapBounds[0], mapBounds[1]);
3968
 
                                break;
3969
 
                        case  5:
3970
 
                                colorMap(rgb, value, mapBounds[0], mapBounds[1]);
3971
 
                                break;
3972
 
                        case  6:
3973
 
                                blueColorMap(rgb, value, mapBounds[0], mapBounds[1]);
3974
 
                                break;
3975
 
                        case  7:
3976
 
                                 randColorMap(rgb, value, mapBounds[0], mapBounds[1]);
3977
 
                                break;
3978
 
                }
 
5240
                //Pick the desired colour map
 
5241
                colourMapWrap(colourMap,rgb,value,mapBounds[0],mapBounds[1]);
3979
5242
        
3980
5243
                d[ui]->r=rgb[0]/255.0f;
3981
5244
                d[ui]->g=rgb[1]/255.0f;
4091
5354
 
4092
5355
        string str,tmpStr;
4093
5356
 
4094
 
        stream_cast(tmpStr,enabled);
4095
 
        s.push_back(std::make_pair("Enabled", tmpStr));
4096
 
        keys.push_back(KEY_IONCOLOURFILTER_ENABLED);
4097
 
        type.push_back(PROPERTY_TYPE_BOOL);
4098
5357
 
4099
5358
        stream_cast(str,NUM_COLOURMAPS);
4100
5359
        str =string("ColourMap (0-") + str + ")";
4134
5393
        needUpdate=false;
4135
5394
        switch(key)
4136
5395
        {
4137
 
                case KEY_IONCLIP_ENABLED:
4138
 
                {
4139
 
                        string stripped=stripWhite(value);
4140
 
 
4141
 
                        if(!(stripped == "1"|| stripped == "0"))
4142
 
                                return false;
4143
 
 
4144
 
                        bool lastVal=enabled;
4145
 
                        if(stripped=="1")
4146
 
                                enabled=true;
4147
 
                        else
4148
 
                                enabled=false;
4149
 
 
4150
 
                        //if the result is different, the
4151
 
                        //cache should be invalidated
4152
 
                        if(lastVal!=enabled)
4153
 
                        {
4154
 
                                needUpdate=true;
4155
 
                                clearCache();
4156
 
                        }
4157
 
 
4158
 
                        break;
4159
 
 
4160
 
                }
4161
5396
                case KEY_IONCOLOURFILTER_COLOURMAP:
4162
5397
                {
4163
5398
                        unsigned int tmpMap;
4343
5578
        fixedBins=0;
4344
5579
        nBins=1000;
4345
5580
        normalise=1;
4346
 
 
 
5581
        errMode.mode=PLOT_ERROR_NONE;
 
5582
        errMode.movingAverageNum=4;
4347
5583
        //Default to blue plot
4348
5584
        r=g=0;
4349
5585
        b=a=1;
4379
5615
        //the appropriate position in the table
4380
5616
        unsigned int rangeID = rng->rangeFile->getRangeID(massToCharge);
4381
5617
 
4382
 
        if(rangeID != (unsigned int)(-1) && (*(rng->enabledRanges))[rangeID])
 
5618
        if(rangeID != (unsigned int)(-1) && rng->enabledRanges[rangeID])
4383
5619
        {
4384
5620
                unsigned int ionID=rng->rangeFile->getIonID(rangeID); 
4385
5621
                unsigned int pos;
4412
5648
        p->b=b; 
4413
5649
        p->a=a; 
4414
5650
        p->plotType=plotType;
4415
 
 
 
5651
        p->errMode=errMode;
4416
5652
        //We are copying wether to cache or not,
4417
5653
        //not the cache itself
4418
5654
        p->cache=cache;
4419
5655
        p->cacheOK=false;
4420
 
        p->enabled=enabled;
4421
5656
        p->progress=progress;
4422
5657
        p->userString=userString;
4423
5658
        return p;
4424
5659
}
4425
5660
 
 
5661
void CompositionProfileFilter::initFilter(const std::vector<const FilterStreamData *> &dataIn,
 
5662
                                std::vector<const FilterStreamData *> &dataOut)
 
5663
{
 
5664
        //Check for range file parent
 
5665
        for(unsigned int ui=0;ui<dataIn.size();ui++)
 
5666
        {
 
5667
                if(dataIn[ui]->getStreamType() == STREAM_TYPE_RANGE)
 
5668
                {
 
5669
                        haveRangeParent=true;
 
5670
                        return;
 
5671
                }
 
5672
        }
 
5673
        haveRangeParent=false;
 
5674
}
 
5675
 
4426
5676
unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStreamData *> &dataIn,
4427
5677
                        std::vector<const FilterStreamData *> &getOut, unsigned int &progress, 
4428
5678
                                                                bool (*callback)(void))
4586
5836
                        //TODO: Might be nice to detect if an ions ranges
4587
5837
                        //are all, disabled then if they are, enter this "if"
4588
5838
                        //anyway
4589
 
                        if((*rngData->enabledIons)[ui])
 
5839
                        if(rngData->enabledIons[ui])
4590
5840
                        {
4591
5841
                                //Keep the forwards mapping for binning
4592
5842
                                ionIDMapping.insert(make_pair(ui,enabledCount));
4777
6027
                plotData[ui]->index=ui;
4778
6028
                plotData[ui]->parent=this;
4779
6029
                plotData[ui]->xLabel= "Distance";
 
6030
                plotData[ui]->errDat=errMode;
4780
6031
                if(normalise)
4781
6032
                {
4782
6033
                        //If we have composition, normalise against 
4820
6071
                }
4821
6072
 
4822
6073
                plotData[ui]->xyData.resize(ionFrequencies[ui].size());
4823
 
#pragma omp parallel for
4824
6074
                for(unsigned int uj=0;uj<ionFrequencies[ui].size(); uj++)
4825
6075
                {
4826
6076
                        float xPos;
4866
6116
                {
4867
6117
                        plotData[ui]->cached=1;
4868
6118
                        filterOutputs.push_back(plotData[ui]);  
4869
 
                        cacheOK=true;
4870
6119
                }
4871
6120
                else
4872
 
                {
4873
6121
                        plotData[ui]->cached=0;
4874
 
                }
4875
6122
 
4876
6123
                plotData[ui]->plotType = plotType;
4877
6124
                getOut.push_back(plotData[ui]);
4878
6125
        }
4879
6126
 
 
6127
        cacheOK=cache;
4880
6128
        return 0;
4881
6129
}
4882
6130
 
4898
6146
                                        const std::string &value, bool &needUpdate) 
4899
6147
{
4900
6148
 
4901
 
        if(key == KEY_COMPPROFILE_ENABLED)
4902
 
        {
4903
 
                string stripped=stripWhite(value);
4904
 
 
4905
 
                if (!(stripped == "1"|| stripped == "0"))
4906
 
                        return false;
4907
 
 
4908
 
                bool lastVal=enabled;
4909
 
                if (stripped=="1")
4910
 
                        enabled=true;
4911
 
                else
4912
 
                        enabled=false;
4913
 
 
4914
 
                //if the result is different, the
4915
 
                //cache should be invalidated
4916
 
                if (lastVal!=enabled)
4917
 
                {
4918
 
                        needUpdate=true;
4919
 
                        clearCache();
4920
 
                }
4921
 
        }
4922
 
        else
4923
 
        {
4924
 
                switch(set)
4925
 
                {
4926
 
                        case 0://Primitive settings
4927
 
                        {
4928
 
                                
4929
 
                                switch(key)
4930
 
                                {
4931
 
                                        case KEY_COMPPROFILE_BINWIDTH:
4932
 
                                        {
4933
 
                                                float newBinWidth;
4934
 
                                                if(stream_cast(newBinWidth,value))
4935
 
                                                        return false;
4936
 
 
4937
 
                                                if(newBinWidth < sqrt(std::numeric_limits<float>::epsilon()))
4938
 
                                                        return false;
4939
 
 
4940
 
                                                binWidth=newBinWidth;
4941
 
                                                clearCache();
4942
 
                                                needUpdate=true;
4943
 
                                                break;
4944
 
                                        }
4945
 
                                        case KEY_COMPPROFILE_FIXEDBINS:
4946
 
                                        {
4947
 
                                                unsigned int valueInt;
4948
 
                                                if(stream_cast(valueInt,value))
4949
 
                                                        return false;
4950
 
 
4951
 
                                                if(valueInt ==0 || valueInt == 1)
4952
 
                                                {
4953
 
                                                        if(fixedBins!= valueInt)
4954
 
                                                        {
4955
 
                                                                needUpdate=true;
4956
 
                                                                fixedBins=valueInt;
4957
 
                                                        }
4958
 
                                                        else
4959
 
                                                                needUpdate=false;
4960
 
                                                }
4961
 
                                                else
4962
 
                                                        return false;
4963
 
                                                clearCache();
4964
 
                                                needUpdate=true;        
4965
 
                                                break;  
4966
 
                                        }
4967
 
                                        case KEY_COMPPROFILE_NORMAL:
4968
 
                                        {
4969
 
                                                Point3D newPt;
4970
 
                                                if(!newPt.parse(value))
4971
 
                                                        return false;
4972
 
 
4973
 
                                                if(!(vectorParams[1] == newPt ))
4974
 
                                                {
4975
 
                                                        vectorParams[1] = newPt;
4976
 
                                                        needUpdate=true;
4977
 
                                                        clearCache();
4978
 
                                                }
4979
 
                                                return true;
4980
 
                                        }
4981
 
                                        case KEY_COMPPROFILE_NUMBINS:
4982
 
                                        {
4983
 
                                                unsigned int newNumBins;
4984
 
                                                if(stream_cast(newNumBins,value))
4985
 
                                                        return false;
4986
 
 
4987
 
                                                nBins=newNumBins;
4988
 
 
4989
 
                                                clearCache();
4990
 
                                                needUpdate=true;
4991
 
                                                break;
4992
 
                                        }
4993
 
                                        case KEY_COMPPROFILE_ORIGIN:
4994
 
                                        {
4995
 
                                                Point3D newPt;
4996
 
                                                if(!newPt.parse(value))
4997
 
                                                        return false;
4998
 
 
4999
 
                                                if(!(vectorParams[0] == newPt ))
5000
 
                                                {
5001
 
                                                        vectorParams[0] = newPt;
5002
 
                                                        needUpdate=true;
5003
 
                                                        clearCache();
5004
 
                                                }
5005
 
 
5006
 
                                                return true;
5007
 
                                        }
5008
 
                                        case KEY_COMPPROFILE_PRIMITIVETYPE:
5009
 
                                        {
5010
 
                                                unsigned int newPrimitive;
5011
 
                                                if(stream_cast(newPrimitive,value) ||
5012
 
                                                                newPrimitive >= COMPPROFILE_PRIMITIVE_END)
5013
 
                                                        return false;
5014
 
                                
5015
 
 
5016
 
                                                //TODO: Convert the type data as best we can.
5017
 
                                                primitiveType=newPrimitive;
5018
 
 
5019
 
                                                //In leiu of covnersion, just reset the primitive
5020
 
                                                //values to some nominal defaults.
5021
 
                                                vectorParams.clear();
5022
 
                                                scalarParams.clear();
5023
 
                                                switch(primitiveType)
5024
 
                                                {
5025
 
                                                        case IONCLIP_PRIMITIVE_CYLINDER:
5026
 
                                                                vectorParams.push_back(Point3D(0,0,0));
5027
 
                                                                vectorParams.push_back(Point3D(0,20,0));
5028
 
                                                                scalarParams.push_back(10.0f);
5029
 
                                                                break;
5030
 
 
5031
 
                                                        default:
5032
 
                                                                ASSERT(false);
5033
 
                                                }
5034
 
                                
5035
 
                                                clearCache();   
5036
 
                                                needUpdate=true;        
5037
 
                                                return true;    
5038
 
                                        }
5039
 
                                        case KEY_COMPPROFILE_RADIUS:
5040
 
                                        {
5041
 
                                                float newRad;
5042
 
                                                if(stream_cast(newRad,value))
5043
 
                                                        return false;
5044
 
 
5045
 
                                                if(scalarParams[0] != newRad )
5046
 
                                                {
5047
 
                                                        scalarParams[0] = newRad;
5048
 
                                                        needUpdate=true;
5049
 
                                                        clearCache();
5050
 
                                                }
5051
 
                                                return true;
5052
 
                                        }
5053
 
                                        case KEY_COMPPROFILE_SHOWPRIMITIVE:
5054
 
                                        {
5055
 
                                                unsigned int valueInt;
5056
 
                                                if(stream_cast(valueInt,value))
5057
 
                                                        return false;
5058
 
 
5059
 
                                                if(valueInt ==0 || valueInt == 1)
5060
 
                                                {
5061
 
                                                        if(showPrimitive!= valueInt)
5062
 
                                                        {
5063
 
                                                                needUpdate=true;
5064
 
                                                                showPrimitive=valueInt;
5065
 
                                                        }
5066
 
                                                        else
5067
 
                                                                needUpdate=false;
5068
 
                                                }
5069
 
                                                else
5070
 
                                                        return false;           
5071
 
                                                break;  
5072
 
                                        }
5073
 
 
5074
 
                                        case KEY_COMPPROFILE_NORMALISE:
5075
 
                                        {
5076
 
                                                unsigned int valueInt;
5077
 
                                                if(stream_cast(valueInt,value))
5078
 
                                                        return false;
5079
 
 
5080
 
                                                if(valueInt ==0 || valueInt == 1)
5081
 
                                                {
5082
 
                                                        if(normalise!= valueInt)
5083
 
                                                        {
5084
 
                                                                needUpdate=true;
5085
 
                                                                normalise=valueInt;
5086
 
                                                        }
5087
 
                                                        else
5088
 
                                                                needUpdate=false;
5089
 
                                                }
5090
 
                                                else
5091
 
                                                        return false;
5092
 
                                                clearCache();
5093
 
                                                needUpdate=true;        
5094
 
                                                break;  
5095
 
                                        }
5096
 
                                }
5097
 
                        }
5098
 
                        case 1: //Plot settings
5099
 
                        {
5100
 
                                switch(key)
5101
 
                                {
5102
 
                                        case KEY_COMPPROFILE_PLOTTYPE:
5103
 
                                        {
5104
 
                                                unsigned int tmpPlotType;
5105
 
 
5106
 
                                                tmpPlotType=plotID(value);
5107
 
 
5108
 
                                                if(tmpPlotType >= PLOT_TYPE_ENDOFENUM)
5109
 
                                                        return false;
5110
 
 
5111
 
                                                plotType = tmpPlotType;
5112
 
                                                needUpdate=true;        
5113
 
                                                break;
5114
 
                                        }
5115
 
                                        case KEY_COMPPROFILE_COLOUR:
5116
 
                                        {
5117
 
                                                unsigned char newR,newG,newB,newA;
5118
 
                                                parseColString(value,newR,newG,newB,newA);
5119
 
 
5120
 
                                                r=((float)newR)/255.0f;
5121
 
                                                g=((float)newG)/255.0f;
5122
 
                                                b=((float)newB)/255.0f;
5123
 
                                                a=1.0;
5124
 
 
5125
 
                                                needUpdate=true;
5126
 
                                                break;  
5127
 
                                        }
5128
 
                                }
5129
 
                        }
5130
 
                                
5131
 
                }
 
6149
        switch(set)
 
6150
        {
 
6151
                case 0://Primitive settings
 
6152
                {
 
6153
                        
 
6154
                        switch(key)
 
6155
                        {
 
6156
                                case KEY_COMPPROFILE_BINWIDTH:
 
6157
                                {
 
6158
                                        float newBinWidth;
 
6159
                                        if(stream_cast(newBinWidth,value))
 
6160
                                                return false;
 
6161
 
 
6162
                                        if(newBinWidth < sqrt(std::numeric_limits<float>::epsilon()))
 
6163
                                                return false;
 
6164
 
 
6165
                                        binWidth=newBinWidth;
 
6166
                                        clearCache();
 
6167
                                        needUpdate=true;
 
6168
                                        break;
 
6169
                                }
 
6170
                                case KEY_COMPPROFILE_FIXEDBINS:
 
6171
                                {
 
6172
                                        unsigned int valueInt;
 
6173
                                        if(stream_cast(valueInt,value))
 
6174
                                                return false;
 
6175
 
 
6176
                                        if(valueInt ==0 || valueInt == 1)
 
6177
                                        {
 
6178
                                                if(fixedBins!= valueInt)
 
6179
                                                {
 
6180
                                                        needUpdate=true;
 
6181
                                                        fixedBins=valueInt;
 
6182
                                                }
 
6183
                                                else
 
6184
                                                        needUpdate=false;
 
6185
                                        }
 
6186
                                        else
 
6187
                                                return false;
 
6188
                                        clearCache();
 
6189
                                        needUpdate=true;        
 
6190
                                        break;  
 
6191
                                }
 
6192
                                case KEY_COMPPROFILE_NORMAL:
 
6193
                                {
 
6194
                                        Point3D newPt;
 
6195
                                        if(!newPt.parse(value))
 
6196
                                                return false;
 
6197
 
 
6198
                                        if(!(vectorParams[1] == newPt ))
 
6199
                                        {
 
6200
                                                vectorParams[1] = newPt;
 
6201
                                                needUpdate=true;
 
6202
                                                clearCache();
 
6203
                                        }
 
6204
                                        return true;
 
6205
                                }
 
6206
                                case KEY_COMPPROFILE_NUMBINS:
 
6207
                                {
 
6208
                                        unsigned int newNumBins;
 
6209
                                        if(stream_cast(newNumBins,value))
 
6210
                                                return false;
 
6211
 
 
6212
                                        nBins=newNumBins;
 
6213
 
 
6214
                                        clearCache();
 
6215
                                        needUpdate=true;
 
6216
                                        break;
 
6217
                                }
 
6218
                                case KEY_COMPPROFILE_ORIGIN:
 
6219
                                {
 
6220
                                        Point3D newPt;
 
6221
                                        if(!newPt.parse(value))
 
6222
                                                return false;
 
6223
 
 
6224
                                        if(!(vectorParams[0] == newPt ))
 
6225
                                        {
 
6226
                                                vectorParams[0] = newPt;
 
6227
                                                needUpdate=true;
 
6228
                                                clearCache();
 
6229
                                        }
 
6230
 
 
6231
                                        return true;
 
6232
                                }
 
6233
                                case KEY_COMPPROFILE_PRIMITIVETYPE:
 
6234
                                {
 
6235
                                        unsigned int newPrimitive;
 
6236
                                        if(stream_cast(newPrimitive,value) ||
 
6237
                                                        newPrimitive >= COMPPROFILE_PRIMITIVE_END)
 
6238
                                                return false;
 
6239
                        
 
6240
 
 
6241
                                        //TODO: Convert the type data as best we can.
 
6242
                                        primitiveType=newPrimitive;
 
6243
 
 
6244
                                        //In leiu of covnersion, just reset the primitive
 
6245
                                        //values to some nominal defaults.
 
6246
                                        vectorParams.clear();
 
6247
                                        scalarParams.clear();
 
6248
                                        switch(primitiveType)
 
6249
                                        {
 
6250
                                                case IONCLIP_PRIMITIVE_CYLINDER:
 
6251
                                                        vectorParams.push_back(Point3D(0,0,0));
 
6252
                                                        vectorParams.push_back(Point3D(0,20,0));
 
6253
                                                        scalarParams.push_back(10.0f);
 
6254
                                                        break;
 
6255
 
 
6256
                                                default:
 
6257
                                                        ASSERT(false);
 
6258
                                        }
 
6259
                        
 
6260
                                        clearCache();   
 
6261
                                        needUpdate=true;        
 
6262
                                        return true;    
 
6263
                                }
 
6264
                                case KEY_COMPPROFILE_RADIUS:
 
6265
                                {
 
6266
                                        float newRad;
 
6267
                                        if(stream_cast(newRad,value))
 
6268
                                                return false;
 
6269
 
 
6270
                                        if(scalarParams[0] != newRad )
 
6271
                                        {
 
6272
                                                scalarParams[0] = newRad;
 
6273
                                                needUpdate=true;
 
6274
                                                clearCache();
 
6275
                                        }
 
6276
                                        return true;
 
6277
                                }
 
6278
                                case KEY_COMPPROFILE_SHOWPRIMITIVE:
 
6279
                                {
 
6280
                                        unsigned int valueInt;
 
6281
                                        if(stream_cast(valueInt,value))
 
6282
                                                return false;
 
6283
 
 
6284
                                        if(valueInt ==0 || valueInt == 1)
 
6285
                                        {
 
6286
                                                if(showPrimitive!= valueInt)
 
6287
                                                {
 
6288
                                                        needUpdate=true;
 
6289
                                                        showPrimitive=valueInt;
 
6290
                                                }
 
6291
                                                else
 
6292
                                                        needUpdate=false;
 
6293
                                        }
 
6294
                                        else
 
6295
                                                return false;           
 
6296
                                        break;  
 
6297
                                }
 
6298
 
 
6299
                                case KEY_COMPPROFILE_NORMALISE:
 
6300
                                {
 
6301
                                        unsigned int valueInt;
 
6302
                                        if(stream_cast(valueInt,value))
 
6303
                                                return false;
 
6304
 
 
6305
                                        if(valueInt ==0 || valueInt == 1)
 
6306
                                        {
 
6307
                                                if(normalise!= valueInt)
 
6308
                                                {
 
6309
                                                        needUpdate=true;
 
6310
                                                        normalise=valueInt;
 
6311
                                                }
 
6312
                                                else
 
6313
                                                        needUpdate=false;
 
6314
                                        }
 
6315
                                        else
 
6316
                                                return false;
 
6317
                                        clearCache();
 
6318
                                        needUpdate=true;        
 
6319
                                        break;  
 
6320
                                }
 
6321
                        }
 
6322
                }
 
6323
                case 1: //Plot settings
 
6324
                {
 
6325
                        switch(key)
 
6326
                        {
 
6327
                                case KEY_COMPPROFILE_PLOTTYPE:
 
6328
                                {
 
6329
                                        unsigned int tmpPlotType;
 
6330
 
 
6331
                                        tmpPlotType=plotID(value);
 
6332
 
 
6333
                                        if(tmpPlotType >= PLOT_TYPE_ENDOFENUM)
 
6334
                                                return false;
 
6335
 
 
6336
                                        plotType = tmpPlotType;
 
6337
                                        needUpdate=true;        
 
6338
                                        break;
 
6339
                                }
 
6340
                                case KEY_COMPPROFILE_COLOUR:
 
6341
                                {
 
6342
                                        unsigned char newR,newG,newB,newA;
 
6343
                                        parseColString(value,newR,newG,newB,newA);
 
6344
 
 
6345
                                        r=((float)newR)/255.0f;
 
6346
                                        g=((float)newG)/255.0f;
 
6347
                                        b=((float)newB)/255.0f;
 
6348
                                        a=1.0;
 
6349
 
 
6350
                                        needUpdate=true;
 
6351
                                        break;  
 
6352
                                }
 
6353
                        }
 
6354
                        break;
 
6355
                }
 
6356
                case 2: //Error estimation settings     
 
6357
                {
 
6358
                        switch(key)
 
6359
                        {
 
6360
                                case KEY_COMPPROFILE_ERRMODE:
 
6361
                                {
 
6362
                                        unsigned int tmpMode;
 
6363
                                        tmpMode=plotErrmodeID(value);
 
6364
 
 
6365
                                        if(tmpMode >= PLOT_ERROR_ENDOFENUM)
 
6366
                                                return false;
 
6367
 
 
6368
                                        errMode.mode= tmpMode;
 
6369
                                        needUpdate=true;
 
6370
 
 
6371
                                        break;
 
6372
                                }
 
6373
                                case KEY_COMPPROFILE_AVGWINSIZE:
 
6374
                                {
 
6375
                                        unsigned int tmpNum;
 
6376
                                        stream_cast(tmpNum,value);
 
6377
                                        if(tmpNum<=1)
 
6378
                                                return 1;
 
6379
 
 
6380
                                        errMode.movingAverageNum=tmpNum;
 
6381
                                        needUpdate=true;
 
6382
                                        break;
 
6383
                                }
 
6384
                                default:
 
6385
                                        ASSERT(false);
 
6386
                                        ;
 
6387
                        }
 
6388
                        break;
 
6389
                }
 
6390
                default:
 
6391
                        ASSERT(false);  
5132
6392
        }
5133
6393
 
5134
6394
        if(needUpdate)
5148
6408
 
5149
6409
        string str,tmpStr;
5150
6410
 
5151
 
        stream_cast(tmpStr,enabled);
5152
 
        s.push_back(std::make_pair("Enabled", tmpStr));
5153
 
        keys.push_back(KEY_COMPPROFILE_ENABLED);
5154
 
        type.push_back(PROPERTY_TYPE_BOOL);
5155
 
        
5156
6411
        //Allow primitive selection if we have more than one primitive
5157
6412
        if(COMPPROFILE_PRIMITIVE_END > 1)
5158
6413
        {
5252
6507
        type.push_back(PROPERTY_TYPE_CHOICE);
5253
6508
        keys.push_back(KEY_COMPPROFILE_PLOTTYPE);
5254
6509
        //Convert the colour to a hex string
5255
 
        string thisCol;
5256
 
        genColString((unsigned char)(r*255.0),(unsigned char)(g*255.0),
5257
 
        (unsigned char)(b*255.0),(unsigned char)(a*255.0),thisCol);
5258
 
 
5259
 
        s.push_back(make_pair(string("Colour"),thisCol)); 
5260
 
        type.push_back(PROPERTY_TYPE_COLOUR);
5261
 
        keys.push_back(KEY_COMPPROFILE_COLOUR);
 
6510
        if(!haveRangeParent)
 
6511
        {
 
6512
                string thisCol;
 
6513
                genColString((unsigned char)(r*255.0),(unsigned char)(g*255.0),
 
6514
                (unsigned char)(b*255.0),(unsigned char)(a*255.0),thisCol);
 
6515
 
 
6516
                s.push_back(make_pair(string("Colour"),thisCol)); 
 
6517
                type.push_back(PROPERTY_TYPE_COLOUR);
 
6518
                keys.push_back(KEY_COMPPROFILE_COLOUR);
 
6519
        }
 
6520
 
 
6521
        propertyList.data.push_back(s);
 
6522
        propertyList.types.push_back(type);
 
6523
        propertyList.keys.push_back(keys);
 
6524
        
 
6525
        s.clear();
 
6526
        type.clear();
 
6527
        keys.clear();
 
6528
 
 
6529
        
 
6530
        choices.clear();
 
6531
        tmpStr=plotErrmodeString(PLOT_ERROR_NONE);
 
6532
        choices.push_back(make_pair((unsigned int) PLOT_ERROR_NONE,tmpStr));
 
6533
        tmpStr=plotErrmodeString(PLOT_ERROR_MOVING_AVERAGE);
 
6534
        choices.push_back(make_pair((unsigned int) PLOT_ERROR_MOVING_AVERAGE,tmpStr));
 
6535
 
 
6536
        tmpStr= choiceString(choices,errMode.mode);
 
6537
        s.push_back(make_pair(string("Err. Estimator"),tmpStr));
 
6538
        type.push_back(PROPERTY_TYPE_CHOICE);
 
6539
        keys.push_back(KEY_COMPPROFILE_ERRMODE);
 
6540
 
 
6541
 
 
6542
        if(errMode.mode == PLOT_ERROR_MOVING_AVERAGE)
 
6543
        {
 
6544
                stream_cast(tmpStr,errMode.movingAverageNum);
 
6545
                s.push_back(make_pair(string("Avg. Window"), tmpStr));
 
6546
                type.push_back(PROPERTY_TYPE_INTEGER);
 
6547
                keys.push_back(KEY_COMPPROFILE_AVGWINSIZE);
 
6548
 
 
6549
        }       
5262
6550
 
5263
6551
        propertyList.data.push_back(s);
5264
6552
        propertyList.types.push_back(type);
5707
6995
        //not the cache itself
5708
6996
        p->cache=cache;
5709
6997
        p->cacheOK=false;
5710
 
        p->enabled=enabled;
5711
6998
        p->progress=progress;
5712
6999
        p->userString=userString;
5713
7000
        return p;
5759
7046
                                if(ptCount == 4)
5760
7047
                                {
5761
7048
                                        bThis.setBounds(p,4);
5762
 
 
5763
 
                                        //TODO: Parallelise this using multiple "bThis" objects, which are then merged.
5764
7049
                                        //Expand the bounding volume
 
7050
#ifdef _OPENMP
 
7051
                                        //Parallel version
 
7052
                                        unsigned int nT =omp_get_max_threads(); 
 
7053
 
 
7054
                                        BoundCube *newBounds= new BoundCube[nT];
 
7055
                                        for(unsigned int ui=0;ui<nT;ui++)
 
7056
                                                newBounds[ui]=bThis;
 
7057
 
 
7058
                                        bool spin=false;
 
7059
                                        #pragma omp parallel for shared(spin)
 
7060
                                        for(unsigned int ui=dataPos;ui<d->data.size();ui++)
 
7061
                                        {
 
7062
                                                unsigned int thisT=omp_get_thread_num();
 
7063
                                                //OpenMP does not allow exiting. Use spin instead
 
7064
                                                if(spin)
 
7065
                                                        continue;
 
7066
 
 
7067
                                                if(!curProg--)
 
7068
                                                {
 
7069
                                                        #pragma omp critical
 
7070
                                                        {
 
7071
                                                        n+=NUM_CALLBACK;
 
7072
                                                        progress= (unsigned int)((float)(n)/((float)totalSize)*100.0f);
 
7073
                                                        }
 
7074
 
 
7075
 
 
7076
                                                        if(thisT == 0)
 
7077
                                                        {
 
7078
                                                                if(!(*callback)())
 
7079
                                                                        spin=true;
 
7080
                                                        }
 
7081
                                                }
 
7082
 
 
7083
                                                newBounds[thisT].expand(d->data[ui].getPos());
 
7084
                                        }
 
7085
                                        if(spin)
 
7086
                                        {                       
 
7087
                                                delete d;
 
7088
                                                return IONDOWNSAMPLE_ABORT_ERR;
 
7089
                                        }
 
7090
 
 
7091
                                        for(unsigned int ui=0;ui<nT;ui++)
 
7092
                                                bThis.expand(newBounds[ui]);
 
7093
 
 
7094
                                        delete[] newBounds;
 
7095
#else
 
7096
                                        //Single thread version
5765
7097
                                        for(unsigned int ui=dataPos;ui<d->data.size();ui++)
5766
7098
                                        {
5767
7099
                                                bThis.expand(d->data[ui].getPos());
5776
7108
                                                        }
5777
7109
                                                }
5778
7110
                                        }
 
7111
#endif
5779
7112
                                        bTotal.expand(bThis);
5780
7113
                                }
5781
7114
 
5927
7260
        vector<pair<string,string> > s;
5928
7261
 
5929
7262
        string tmpStr;
5930
 
        stream_cast(tmpStr,enabled);
5931
 
        s.push_back(std::make_pair("Enabled", tmpStr));
5932
 
        keys.push_back(KEY_BOUNDINGBOX_ENABLED);
5933
 
        type.push_back(PROPERTY_TYPE_BOOL);
5934
 
        
5935
7263
        stream_cast(tmpStr,isVisible);
5936
7264
        s.push_back(std::make_pair("Visible", tmpStr));
5937
7265
        keys.push_back(KEY_BOUNDINGBOX_VISIBLE);
6022
7350
        needUpdate=false;
6023
7351
        switch(key)
6024
7352
        {
6025
 
                case KEY_BOUNDINGBOX_ENABLED:
6026
 
                {
6027
 
                        string stripped=stripWhite(value);
6028
 
 
6029
 
                        if(!(stripped == "1"|| stripped == "0"))
6030
 
                                return false;
6031
 
 
6032
 
                        bool lastVal=enabled;
6033
 
                        if(stripped=="1")
6034
 
                                enabled=true;
6035
 
                        else
6036
 
                                enabled=false;
6037
 
 
6038
 
                        //if the result is different, the
6039
 
                        //cache should be invalidated
6040
 
                        if(lastVal!=enabled)
6041
 
                        {
6042
 
                                needUpdate=true;
6043
 
                                clearCache();
6044
 
                        }
6045
 
 
6046
 
                        break;
6047
 
 
6048
 
                }
6049
 
 
6050
7353
                case KEY_BOUNDINGBOX_VISIBLE:
6051
7354
                {
6052
7355
                        string stripped=stripWhite(value);
6444
7747
TransformFilter::TransformFilter()
6445
7748
{
6446
7749
        transformMode=TRANSFORM_TRANSLATE;
 
7750
        originMode=TRANSFORM_ORIGINMODE_SELECT;
6447
7751
        //Set up default value
6448
7752
        vectorParams.resize(1);
6449
7753
        vectorParams[0] = Point3D(0,0,0);
 
7754
        
 
7755
        showPrimitive=true;
6450
7756
 
6451
7757
        cacheOK=false;
6452
7758
        cache=false; 
6463
7769
        std::copy(vectorParams.begin(),vectorParams.end(),p->vectorParams.begin());
6464
7770
        std::copy(scalarParams.begin(),scalarParams.end(),p->scalarParams.begin());
6465
7771
 
6466
 
 
 
7772
        p->showPrimitive=showPrimitive;
 
7773
        p->originMode=originMode;
6467
7774
        //We are copying wether to cache or not,
6468
7775
        //not the cache itself
6469
7776
        p->cache=cache;
6470
7777
        p->cacheOK=false;
6471
 
        p->enabled=enabled;
6472
7778
        p->progress=progress;
6473
7779
        p->userString=userString;
6474
7780
        return p;
6483
7789
unsigned int TransformFilter::refresh(const std::vector<const FilterStreamData *> &dataIn,
6484
7790
        std::vector<const FilterStreamData *> &getOut, unsigned int &progress, bool (*callback)(void))
6485
7791
{
 
7792
        //Clear selection devices FIXME: Is this a memory leak???
 
7793
        devices.clear();
 
7794
        if(showPrimitive)
 
7795
        {
 
7796
                //If the user is using a transform mode that requires origin selection 
 
7797
                if( originMode == TRANSFORM_ORIGINMODE_SELECT && 
 
7798
                        showOrigin && (transformMode == TRANSFORM_ROTATE ||
 
7799
                                transformMode == TRANSFORM_SCALE) )
 
7800
                {
 
7801
                        //construct a new primitive, do not cache
 
7802
                        DrawStreamData *drawData=new DrawStreamData;
 
7803
                        //Add drawable components
 
7804
                        DrawSphere *dS = new DrawSphere;
 
7805
                        dS->setOrigin(vectorParams[0]);
 
7806
                        dS->setRadius(1);
 
7807
                        //FIXME: Alpha blending is all screwed up. May require more
 
7808
                        //advanced drawing in scene. (front-back drawing).
 
7809
                        //I have set alpha=1 for now.
 
7810
                        dS->setColour(0.2,0.2,0.8,1.0);
 
7811
                        dS->setLatSegments(40);
 
7812
                        dS->setLongSegments(40);
 
7813
                        dS->wantsLight=true;
 
7814
                        drawData->drawables.push_back(dS);
 
7815
 
 
7816
                        //Set up selection "device" for user interaction
 
7817
                        //Note the order of s->addBinding is critical,
 
7818
                        //as bindings are selected by first match.
 
7819
                        //====
 
7820
                        //The object is selectable
 
7821
                        dS->canSelect=true;
 
7822
 
 
7823
                        SelectionDevice *s = new SelectionDevice(this);
 
7824
                        SelectionBinding b;
 
7825
 
 
7826
                        b.setBinding(SELECT_BUTTON_LEFT,FLAG_CMD,
 
7827
                                BINDING_SPHERE_ORIGIN,dS->originPtr(),dS);      
 
7828
                        b.setInteractionMode(BIND_MODE_POINT3D_TRANSLATE);
 
7829
                        s->addBinding(b);
 
7830
                        
 
7831
                        devices.push_back(s);
 
7832
                        drawData->cached=false; 
 
7833
                        getOut.push_back(drawData);
 
7834
                }
 
7835
                
 
7836
        }
6486
7837
        //use the cached copy if we have it.
6487
7838
        if(cacheOK)
6488
7839
        {
6489
7840
                ASSERT(filterOutputs.size());
6490
7841
                for(unsigned int ui=0;ui<dataIn.size();ui++)
6491
 
                        getOut.push_back(dataIn[ui]);
 
7842
                {
 
7843
                        if(dataIn[ui]->getStreamType() != STREAM_TYPE_IONS)
 
7844
                                getOut.push_back(dataIn[ui]);
 
7845
                }
6492
7846
 
6493
7847
                for(unsigned int ui=0;ui<filterOutputs.size();ui++)
6494
7848
                        getOut.push_back(filterOutputs[ui]);
6496
7850
                return 0;
6497
7851
        }
6498
7852
 
 
7853
 
 
7854
        //The user is allowed to choose the mode by which the origin is computed
 
7855
        //so set the origin variable depending upon this
 
7856
        switch(originMode)
 
7857
        {
 
7858
                case TRANSFORM_ORIGINMODE_CENTREBOUND:
 
7859
                {
 
7860
                        BoundCube masterB;
 
7861
                        masterB.setInverseLimits();
 
7862
                        #pragma omp parallel for
 
7863
                        for(unsigned int ui=0;ui<dataIn.size() ;ui++)
 
7864
                        {
 
7865
                                BoundCube thisB;
 
7866
 
 
7867
                                if(dataIn[ui]->getStreamType() == STREAM_TYPE_IONS)
 
7868
                                {
 
7869
                                        const IonStreamData* ions;
 
7870
                                        ions = (const IonStreamData*)dataIn[ui];
 
7871
                                        thisB = getIonDataLimits(ions->data);
 
7872
                                        #pragma omp critical
 
7873
                                        masterB.expand(thisB);
 
7874
                                }
 
7875
                        }
 
7876
 
 
7877
                        if(!masterB.isValid())
 
7878
                                vectorParams[0]=Point3D(0,0,0);
 
7879
                        else
 
7880
                                vectorParams[0]=masterB.getCentroid();
 
7881
                }
 
7882
                case TRANSFORM_ORIGINMODE_MASSCENTRE:
 
7883
                {
 
7884
                        Point3D massCentre(0,0,0);
 
7885
                        #pragma omp parallel for
 
7886
                        for(unsigned int ui=0;ui<dataIn.size() ;ui++)
 
7887
                        {
 
7888
                                if(dataIn[ui]->getStreamType() == STREAM_TYPE_IONS)
 
7889
                                {
 
7890
                                        const IonStreamData* ions;
 
7891
                                        ions = (const IonStreamData*)dataIn[ui];
 
7892
 
 
7893
                                        Point3D thisCentre;
 
7894
                                        thisCentre=Point3D(0,0,0);
 
7895
                                        for(unsigned int uj=0;uj<ions->data.size();uj++)
 
7896
                                                thisCentre+=ions->data[uj].getPos();
 
7897
                                        #pragma omp critical
 
7898
                                        massCentre+=thisCentre*1.0/(float)ions->data.size();
 
7899
                                }
 
7900
                        }
 
7901
                        vectorParams[0]=massCentre;
 
7902
 
 
7903
                }
 
7904
                case TRANSFORM_ORIGINMODE_SELECT:
 
7905
                        break;
 
7906
                default:
 
7907
                        ASSERT(false);
 
7908
        }
 
7909
 
 
7910
        //Apply the transformations to the incoming 
 
7911
        //ion streams, generating new outgoing ion streams with
 
7912
        //the modified positions
6499
7913
        size_t totalSize=numElements(dataIn);
6500
 
        //Compute the bounding box of the incoming streams
6501
7914
        for(unsigned int ui=0;ui<dataIn.size() ;ui++)
6502
7915
        {
6503
7916
                switch(transformMode)
6508
7921
                                //around the specified origin.
6509
7922
                                ASSERT(vectorParams.size() == 1);
6510
7923
                                ASSERT(scalarParams.size() == 1);
6511
 
                                Point3D origin =vectorParams[0];
6512
7924
                                float scaleFactor=scalarParams[0];
 
7925
                                Point3D origin=vectorParams[0];
6513
7926
 
6514
7927
                                size_t n=0;
6515
7928
                                switch(dataIn[ui]->getStreamType())
6529
7942
 
6530
7943
                                                ASSERT(src->data.size() <= totalSize);
6531
7944
                                                unsigned int curProg=NUM_CALLBACK;
 
7945
#ifdef _OPENMP
 
7946
                                                //Parallel version
 
7947
                                                bool spin=false;
 
7948
                                                #pragma omp parallel for shared(spin)
 
7949
                                                for(unsigned int ui=0;ui<src->data.size();ui++)
 
7950
                                                {
 
7951
                                                        unsigned int thisT=omp_get_thread_num();
 
7952
                                                        if(spin)
 
7953
                                                                continue;
 
7954
 
 
7955
                                                        if(!curProg--)
 
7956
                                                        {
 
7957
                                                                #pragma omp critical
 
7958
                                                                {
 
7959
                                                                n+=NUM_CALLBACK;
 
7960
                                                                progress= (unsigned int)((float)(n)/((float)totalSize)*100.0f);
 
7961
                                                                }
 
7962
 
 
7963
 
 
7964
                                                                if(thisT == 0)
 
7965
                                                                {
 
7966
                                                                        if(!(*callback)())
 
7967
                                                                                spin=true;
 
7968
                                                                }
 
7969
                                                        }
 
7970
 
 
7971
 
 
7972
                                                        //set the position for the given ion
 
7973
                                                        d->data[ui].setPos((src->data[ui].getPos() - origin)*scaleFactor+origin);
 
7974
                                                        d->data[ui].setMassToCharge(src->data[ui].getMassToCharge());
 
7975
                                                }
 
7976
                                                if(spin)
 
7977
                                                {                       
 
7978
                                                        delete d;
 
7979
                                                        return TRANSFORM_CALLBACK_FAIL;
 
7980
                                                }
 
7981
 
 
7982
#else
 
7983
                                                //Single threaded version
6532
7984
                                                size_t pos=0;
6533
7985
                                                //Copy across the ions into the target
6534
7986
                                                for(vector<IonHit>::const_iterator it=src->data.begin();
6552
8004
                                                        pos++;
6553
8005
                                                }
6554
8006
 
 
8007
                                                ASSERT(pos == d->data.size());
 
8008
#endif
6555
8009
                                                ASSERT(d->data.size() == src->data.size());
6556
 
                                                ASSERT(pos == d->data.size());
6557
8010
 
6558
8011
                                                if(cache)
6559
8012
                                                {
6600
8053
 
6601
8054
                                                ASSERT(src->data.size() <= totalSize);
6602
8055
                                                unsigned int curProg=NUM_CALLBACK;
 
8056
#ifdef _OPENMP
 
8057
                                                //Parallel version
 
8058
                                                bool spin=false;
 
8059
                                                #pragma omp parallel for shared(spin)
 
8060
                                                for(unsigned int ui=0;ui<src->data.size();ui++)
 
8061
                                                {
 
8062
                                                        unsigned int thisT=omp_get_thread_num();
 
8063
                                                        if(spin)
 
8064
                                                                continue;
 
8065
 
 
8066
                                                        if(!curProg--)
 
8067
                                                        {
 
8068
                                                                #pragma omp critical
 
8069
                                                                {
 
8070
                                                                n+=NUM_CALLBACK;
 
8071
                                                                progress= (unsigned int)((float)(n)/((float)totalSize)*100.0f);
 
8072
                                                                }
 
8073
 
 
8074
 
 
8075
                                                                if(thisT == 0)
 
8076
                                                                {
 
8077
                                                                        if(!(*callback)())
 
8078
                                                                                spin=true;
 
8079
                                                                }
 
8080
                                                        }
 
8081
 
 
8082
 
 
8083
                                                        //set the position for the given ion
 
8084
                                                        d->data[ui].setPos((src->data[ui].getPos() - origin));
 
8085
                                                        d->data[ui].setMassToCharge(src->data[ui].getMassToCharge());
 
8086
                                                }
 
8087
                                                if(spin)
 
8088
                                                {                       
 
8089
                                                        delete d;
 
8090
                                                        return TRANSFORM_CALLBACK_FAIL;
 
8091
                                                }
 
8092
 
 
8093
#else
 
8094
                                                //Single threaded version
6603
8095
                                                size_t pos=0;
6604
8096
                                                //Copy across the ions into the target
6605
8097
                                                for(vector<IonHit>::const_iterator it=src->data.begin();
6622
8114
                                                        }
6623
8115
                                                        pos++;
6624
8116
                                                }
6625
 
 
 
8117
                                                ASSERT(pos == d->data.size());
 
8118
#endif
6626
8119
                                                ASSERT(d->data.size() == src->data.size());
6627
 
                                                ASSERT(pos == d->data.size());
6628
8120
                                                if(cache)
6629
8121
                                                {
6630
8122
                                                        d->cached=1;
6646
8138
                        }
6647
8139
                        case TRANSFORM_ROTATE:
6648
8140
                        {
 
8141
                                Point3D origin=vectorParams[0];
6649
8142
                                switch(dataIn[ui]->getStreamType())
6650
8143
                                {
6651
8144
                                        case STREAM_TYPE_IONS:
6653
8146
                                                //Set up scaling output ion stream 
6654
8147
                                                IonStreamData *d=new IonStreamData;
6655
8148
 
6656
 
                                                cerr << "Allocated :" << d << " in " << __FUNCTION__ << endl;
6657
8149
                                                const IonStreamData *src = (const IonStreamData *)dataIn[ui];
6658
8150
                                                d->data.resize(src->data.size());
6659
8151
                                                d->r = src->r;
6667
8159
                                                //around the specified origin.
6668
8160
                                                ASSERT(vectorParams.size() == 2);
6669
8161
                                                ASSERT(scalarParams.size() == 1);
6670
 
                                                Point3D origin =vectorParams[0];
6671
8162
                                                Point3D axis =vectorParams[1];
6672
8163
                                                axis.normalise();
6673
8164
                                                float angle=scalarParams[0]*M_PI/180.0f;
6674
8165
 
6675
8166
                                                unsigned int curProg=NUM_CALLBACK;
6676
 
                                                size_t pos=0;
6677
8167
                                                size_t n=0;
6678
8168
 
6679
8169
                                                Point3f rotVec,p;
6686
8176
                                                //Generate the rotating quaternions
6687
8177
                                                quat_get_rot_quats(&rotVec,-angle,&q1,&q2);
6688
8178
                                                ASSERT(src->data.size() <= totalSize);
 
8179
 
 
8180
 
 
8181
#ifdef _OPENMP
 
8182
                                                //Parallel version
 
8183
                                                bool spin=false;
 
8184
                                                #pragma omp parallel for shared(spin)
 
8185
                                                for(unsigned int ui=0;ui<src->data.size();ui++)
 
8186
                                                {
 
8187
                                                        unsigned int thisT=omp_get_thread_num();
 
8188
                                                        if(spin)
 
8189
                                                                continue;
 
8190
 
 
8191
                                                        p.fx=src->data[ui].getPos()[0]-origin[0];
 
8192
                                                        p.fy=src->data[ui].getPos()[1]-origin[1];
 
8193
                                                        p.fz=src->data[ui].getPos()[2]-origin[2];
 
8194
                                                        quat_rot_apply_quats(&p,&q1,&q2);
 
8195
                                                        //set the position for the given ion
 
8196
                                                        d->data[ui].setPos(p.fx,p.fy,p.fz);
 
8197
                                                        d->data[ui].setMassToCharge(src->data[ui].getMassToCharge());
 
8198
                                                        if(!curProg--)
 
8199
                                                        {
 
8200
                                                                #pragma omp critical
 
8201
                                                                {
 
8202
                                                                n+=NUM_CALLBACK;
 
8203
                                                                progress= (unsigned int)((float)(n)/((float)totalSize)*100.0f);
 
8204
                                                                }
 
8205
 
 
8206
 
 
8207
                                                                if(thisT == 0)
 
8208
                                                                {
 
8209
                                                                        if(!(*callback)())
 
8210
                                                                                spin=true;
 
8211
                                                                }
 
8212
                                                        }
 
8213
 
 
8214
                                                        //set the uiition for the given ion
 
8215
                                                        d->data[ui].setPos(p.fx,p.fy,p.fz);
 
8216
                                                        d->data[ui].setMassToCharge(src->data[ui].getMassToCharge());
 
8217
 
 
8218
                                                        //set the position for the given ion
 
8219
                                                }
 
8220
 
 
8221
                                                if(spin)
 
8222
                                                {                       
 
8223
                                                        delete d;
 
8224
                                                        return TRANSFORM_CALLBACK_FAIL;
 
8225
                                                }
 
8226
#else
 
8227
                                                size_t pos=0;
 
8228
 
6689
8229
                                                //Copy across the ions into the target
6690
8230
                                                for(vector<IonHit>::const_iterator it=src->data.begin();
6691
8231
                                                               it!=src->data.end(); it++)
6711
8251
                                                        }
6712
8252
                                                        pos++;
6713
8253
                                                }
6714
 
 
 
8254
#endif
6715
8255
                                                ASSERT(d->data.size() == src->data.size());
6716
8256
                                                if(cache)
6717
8257
                                                {
6748
8288
        vector<pair<string,string> > s;
6749
8289
 
6750
8290
        string tmpStr;
6751
 
        stream_cast(tmpStr,enabled);
6752
 
        s.push_back(std::make_pair("Enabled", tmpStr));
6753
 
        keys.push_back(KEY_TRANSFORM_ENABLED);
6754
 
        type.push_back(PROPERTY_TYPE_BOOL);
6755
 
        
6756
8291
        vector<pair<unsigned int,string> > choices;
6757
8292
        choices.push_back(make_pair((unsigned int) TRANSFORM_TRANSLATE,"Translate"));
6758
8293
        choices.push_back(make_pair((unsigned int)TRANSFORM_SCALE,"Scale"));
6763
8298
        s.push_back(make_pair(string("Mode"),tmpStr));
6764
8299
        type.push_back(PROPERTY_TYPE_CHOICE);
6765
8300
        keys.push_back(KEY_TRANSFORM_MODE);
 
8301
        
 
8302
        propertyList.data.push_back(s);
 
8303
        propertyList.types.push_back(type);
 
8304
        propertyList.keys.push_back(keys);
 
8305
        s.clear();type.clear();keys.clear();
 
8306
        
 
8307
        if(transformMode != TRANSFORM_TRANSLATE)
 
8308
        {
 
8309
                vector<pair<unsigned int,string> > choices;
 
8310
                for(unsigned int ui=0;ui<TRANSFORM_ORIGINMODE_END;ui++)
 
8311
                        choices.push_back(make_pair(ui,getOriginTypeString(ui)));
 
8312
                
 
8313
                tmpStr= choiceString(choices,originMode);
 
8314
 
 
8315
                s.push_back(make_pair(string("Origin mode"),tmpStr));
 
8316
                type.push_back(PROPERTY_TYPE_CHOICE);
 
8317
                keys.push_back(KEY_TRANSFORM_ORIGINMODE);
 
8318
        }
6766
8319
 
6767
8320
        switch(transformMode)
6768
8321
        {
6781
8334
                {
6782
8335
                        ASSERT(vectorParams.size() == 1);
6783
8336
                        ASSERT(scalarParams.size() == 1);
6784
 
                        stream_cast(tmpStr,vectorParams[0]);
6785
 
                        keys.push_back(KEY_TRANSFORM_ORIGIN);
6786
 
                        s.push_back(make_pair("Origin", tmpStr));
6787
 
                        type.push_back(PROPERTY_TYPE_POINT3D);
 
8337
                        
 
8338
 
 
8339
                        if(originMode == TRANSFORM_ORIGINMODE_SELECT)
 
8340
                        {
 
8341
                                stream_cast(tmpStr,vectorParams[0]);
 
8342
                                keys.push_back(KEY_TRANSFORM_ORIGIN);
 
8343
                                s.push_back(make_pair("Origin", tmpStr));
 
8344
                                type.push_back(PROPERTY_TYPE_POINT3D);
 
8345
                        }
6788
8346
 
6789
8347
                        stream_cast(tmpStr,scalarParams[0]);
6790
8348
                        keys.push_back(KEY_TRANSFORM_SCALEFACTOR);
6796
8354
                {
6797
8355
                        ASSERT(vectorParams.size() == 2);
6798
8356
                        ASSERT(scalarParams.size() == 1);
6799
 
                        stream_cast(tmpStr,vectorParams[0]);
6800
 
                        keys.push_back(KEY_TRANSFORM_ORIGIN);
6801
 
                        s.push_back(make_pair("Origin", tmpStr));
6802
 
                        type.push_back(PROPERTY_TYPE_POINT3D);
6803
 
 
 
8357
                        if(originMode == TRANSFORM_ORIGINMODE_SELECT)
 
8358
                        {
 
8359
                                stream_cast(tmpStr,vectorParams[0]);
 
8360
                                keys.push_back(KEY_TRANSFORM_ORIGIN);
 
8361
                                s.push_back(make_pair("Origin", tmpStr));
 
8362
                                type.push_back(PROPERTY_TYPE_POINT3D);
 
8363
                        }
6804
8364
                        stream_cast(tmpStr,vectorParams[1]);
6805
8365
                        keys.push_back(KEY_TRANSFORM_ROTATE_AXIS);
6806
8366
                        s.push_back(make_pair("Axis", tmpStr));
6813
8373
                        break;
6814
8374
                        break;
6815
8375
                }
 
8376
        
 
8377
                default:
 
8378
                        ASSERT(false);
6816
8379
        }
6817
8380
 
6818
8381
        propertyList.data.push_back(s);
6916
8479
                        return true;
6917
8480
                }
6918
8481
                        break;
 
8482
                case KEY_TRANSFORM_ORIGINMODE:
 
8483
                {
 
8484
                        size_t i;
 
8485
                        for (i = 0; i < TRANSFORM_MODE_ENUM_END; i++)
 
8486
                                if (value == getOriginTypeString(i)) break;
 
8487
                
 
8488
                        if( i == TRANSFORM_MODE_ENUM_END)
 
8489
                                return false;
 
8490
 
 
8491
                        if(originMode != i)
 
8492
                        {
 
8493
                                originMode = i;
 
8494
                                needUpdate=true;
 
8495
                                clearCache();
 
8496
                        }
 
8497
                        return true;
 
8498
                }
 
8499
 
6919
8500
                default:
6920
8501
                        ASSERT(false);
6921
8502
        }       
6939
8520
                {       
6940
8521
                        f << tabs(depth) << "<transform>" << endl;
6941
8522
                        f << tabs(depth+1) << "<userstring value=\""<<userString << "\"/>"  << endl;
6942
 
                        f << tabs(depth+1) << "<transformmode value=\"" << transformMode        << "\"/>"<<endl;
6943
 
                        
 
8523
                        f << tabs(depth+1) << "<transformmode value=\"" << transformMode<< "\"/>"<<endl;
 
8524
                        f << tabs(depth+1) << "<originmode value=\"" << originMode<< "\"/>"<<endl;
 
8525
                        f << tabs(depth+1) << "<showorigin value=\"" << (int)showOrigin<< "\"/>"<<endl;
 
8526
                                
6944
8527
                        f << tabs(depth+1) << "<vectorparams>" << endl;
6945
8528
                        for(unsigned int ui=0; ui<vectorParams.size(); ui++)
6946
8529
                        {
6999
8582
        xmlFree(xmlString);
7000
8583
        //====
7001
8584
        
 
8585
        //Retrieve origination type 
 
8586
        //====
 
8587
        if(XMLHelpFwdToElem(nodePtr,"originmode"))
 
8588
                return false;
 
8589
 
 
8590
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"value");
 
8591
        if(!xmlString)
 
8592
                return false;
 
8593
        tmpStr=(char *)xmlString;
 
8594
 
 
8595
        //convert from string to digit
 
8596
        if(stream_cast(originMode,tmpStr))
 
8597
                return false;
 
8598
 
 
8599
        if(originMode>= TRANSFORM_ORIGINMODE_END)
 
8600
               return false;    
 
8601
        xmlFree(xmlString);
 
8602
        //====
 
8603
        
 
8604
        //Retrieve origination type 
 
8605
        //====
 
8606
        if(XMLHelpFwdToElem(nodePtr,"showorigin"))
 
8607
                return false;
 
8608
 
 
8609
        xmlString=xmlGetProp(nodePtr,(const xmlChar *)"value");
 
8610
        if(!xmlString)
 
8611
                return false;
 
8612
        tmpStr=(char *)xmlString;
 
8613
 
 
8614
        //convert from string to digit
 
8615
        if(stream_cast(showOrigin,tmpStr))
 
8616
                return false;
 
8617
        
 
8618
        xmlFree(xmlString);
 
8619
        //====
7002
8620
        
7003
8621
        //Retreive vector parameters
7004
8622
        //===
7099
8717
}
7100
8718
 
7101
8719
 
 
8720
void TransformFilter::setPropFromBinding(const SelectionBinding &b)
 
8721
{
 
8722
        switch(b.getID())
 
8723
        {
 
8724
                case BINDING_SPHERE_ORIGIN:
 
8725
                        b.getValue(vectorParams[0]);
 
8726
                        break;
 
8727
                default:
 
8728
                        ASSERT(false);
 
8729
        }
 
8730
        clearCache();
 
8731
}
7102
8732
 
 
8733
std::string TransformFilter::getOriginTypeString(unsigned int i) const
 
8734
{
 
8735
        switch(i)
 
8736
        {
 
8737
                case TRANSFORM_ORIGINMODE_SELECT:
 
8738
                        return std::string("Specify");
 
8739
                case TRANSFORM_ORIGINMODE_CENTREBOUND:
 
8740
                        return std::string("Boundbox Centre");
 
8741
                case TRANSFORM_ORIGINMODE_MASSCENTRE:
 
8742
                        return std::string("Mass Centre");
 
8743
        }
 
8744
}
7103
8745
 
7104
8746
 
7105
8747
//=== External program filter === 
7124
8766
        //not the cache itself
7125
8767
        p->cache=cache;
7126
8768
        p->cacheOK=false;
7127
 
        p->enabled=enabled;
7128
8769
        p->progress=progress;
7129
8770
        p->userString=userString;
7130
8771
        return p;
7374
9015
                        d->a=1.0;
7375
9016
                        d->ionSize = 2.0;
7376
9017
 
7377
 
                        int index[4] = {0, 1, 2, 3};
7378
 
                        if(GenericLoadFloatFile(4, index, d->data,sTmp.c_str(),dummy,0))
 
9018
                        int index2[] = {0, 1, 2, 3};
 
9019
                        if(GenericLoadFloatFile(4, 4, index2, d->data,sTmp.c_str(),dummy,0))
7379
9020
                                return EXTERNALPROG_READPOS_FAIL;
7380
9021
 
7381
9022
 
7406
9047
                        wxString wxTmpStr;
7407
9048
                        wxTmpStr=(*a)[ui];
7408
9049
                        sTmp = stlStr(wxTmpStr);
7409
 
                        cerr << "Opening plot file " << sTmp << endl;
7410
9050
 
7411
9051
                        vector<vector<float> > dataVec;
7412
9052
 
7429
9069
                        //well we ran out of delimiters. bad luck
7430
9070
                        if(!delimString[uj] || !dataVec.size())
7431
9071
                        {
7432
 
                                cerr << "Failed reading file " << sTmp << endl;
7433
9072
                                return EXTERNALPROG_READPLOT_FAIL;
7434
9073
                        }
7435
9074
 
7436
 
                        cerr << "reading file OK" << sTmp << endl;
7437
9075
 
7438
9076
                        //Check that the input has the correct size
7439
9077
                        for(unsigned int uj=0;uj<dataVec.size()-1;uj+=2)
7482
9120
                                                                dataVec[uj+1][uk]);
7483
9121
                                }
7484
9122
                                
7485
 
                                cerr << "Pushing plot data to output " << sTmp << endl;
7486
9123
                                if(alwaysCache)
7487
9124
                                {
7488
9125
                                        d->cached=1;
7518
9155
        vector<pair<string,string> > s;
7519
9156
 
7520
9157
        std::string tmpStr;
7521
 
        stream_cast(tmpStr,enabled);
7522
 
        s.push_back(std::make_pair("Enabled", tmpStr));
7523
 
        keys.push_back(KEY_EXTERNALPROGRAM_ENABLED);
7524
 
        type.push_back(PROPERTY_TYPE_BOOL);
7525
9158
        
7526
9159
        s.push_back(make_pair("Command", commandLine));
7527
9160
        type.push_back(PROPERTY_TYPE_STRING);
7734
9367
        //not the cache itself
7735
9368
        p->cache=cache;
7736
9369
        p->cacheOK=false;
7737
 
        p->enabled=enabled;
7738
9370
        p->progress=progress;
7739
9371
        p->userString=userString;
7740
9372
        return p;
7807
9439
                                d=((const IonStreamData *)dataIn[ui]);
7808
9440
 
7809
9441
                                unsigned int curProg=NUM_CALLBACK;
 
9442
#ifdef _OPENMP
 
9443
                                //Parallel version
 
9444
                                bool spin=false;
 
9445
                                #pragma omp parallel for shared(spin)
 
9446
                                for(size_t ui=0;ui<d->data.size();ui++)
 
9447
                                {
 
9448
                                        unsigned int thisT=omp_get_thread_num();
 
9449
                                        if(spin)
 
9450
                                                continue;
 
9451
                                        p[dataSize + ui] = d->data[ui].getPos();
 
9452
                                        
 
9453
                                        //update progress every CALLBACK ions
 
9454
                                        if(!curProg--)
 
9455
                                        {
 
9456
                                                #pragma omp critical
 
9457
                                                {
 
9458
                                                n+=NUM_CALLBACK;
 
9459
                                                progress= (unsigned int)(((float)(n*(maxProgress-minProgress))/((float)totalDataSize)+minProgress)*100.0f);
 
9460
                                                }
 
9461
 
 
9462
 
 
9463
                                                if(thisT == 0)
 
9464
                                                {
 
9465
                                                        if(!(*callback)())
 
9466
                                                                spin=true;
 
9467
                                                }
 
9468
                                        }
 
9469
 
 
9470
                                }
 
9471
#else
7810
9472
                                for(size_t ui=0;ui<d->data.size();ui++)
7811
9473
                                {
7812
9474
                                        p[dataSize + ui] = d->data[ui].getPos();
7824
9486
                                        
7825
9487
 
7826
9488
                                }
 
9489
#endif
7827
9490
                                dataSize+=d->data.size();
7828
9491
                        }
7829
9492
                        break;  
7877
9540
 
7878
9541
                                                //Adjust this number to provide more update thanusual, because we
7879
9542
                                                //are not doing an o(1) task between updates; yes, it is  hack
7880
 
                                                unsigned int curProg=NUM_CALLBACK/(10*nnMax);
 
9543
                                                unsigned int curProg=NUM_CALLBACK/(100*nnMax);
7881
9544
                                                newD->data.resize(d->data.size());
7882
9545
                                                if(stopMode == SPATIAL_DENSITY_NEIGHBOUR)
7883
9546
                                                {
 
9547
                                                        bool spin=false;
 
9548
                                                        #pragma omp parallel for
7884
9549
                                                        for(size_t ui=0;ui<d->data.size();ui++)
7885
9550
                                                        {
 
9551
                                                                if(spin)
 
9552
                                                                        continue;
7886
9553
                                                                Point3D r;
7887
9554
                                                                vector<const Point3D *> res;
7888
9555
                                                                float maxSqrRad;
7904
9571
                                                                //Update callback as needed
7905
9572
                                                                if(!curProg--)
7906
9573
                                                                {
7907
 
                                                                        n+=NUM_CALLBACK/(10*nnMax);
 
9574
                                                                        #pragma omp critical 
 
9575
                                                                        {
 
9576
                                                                        n+=NUM_CALLBACK/(nnMax);
7908
9577
                                                                        progress= (unsigned int)(((float)(n*(maxProgress-minProgress))/
7909
9578
                                                                                        ((float)totalDataSize)+minProgress)*100.0f);
7910
9579
                                                                        if(!(*callback)())
7911
 
                                                                        {
7912
 
                                                                                delete newD;
7913
 
                                                                                return SPATIAL_ANALYSIS_ABORT_ERR;
 
9580
                                                                                spin=true;
 
9581
                                                                        curProg=NUM_CALLBACK/(nnMax);
7914
9582
                                                                        }
7915
 
                                                                        curProg=NUM_CALLBACK/(10*nnMax);
7916
9583
                                                                }
7917
9584
                                                        }
 
9585
 
 
9586
                                                        if(spin)
 
9587
                                                        {
 
9588
                                                                delete newD;
 
9589
                                                                return SPATIAL_ANALYSIS_ABORT_ERR;
 
9590
                                                        }
 
9591
 
7918
9592
        
7919
9593
                                                }
7920
9594
                                                else if(stopMode == SPATIAL_DENSITY_RADIUS)
8018
9692
        vector<pair<string,string> > s;
8019
9693
 
8020
9694
        string tmpStr;
8021
 
        stream_cast(tmpStr,enabled);
8022
 
        s.push_back(std::make_pair("Enabled", tmpStr));
8023
 
        keys.push_back(KEY_SPATIALANALYSIS_ENABLED);
8024
 
        type.push_back(PROPERTY_TYPE_BOOL);
8025
9695
        vector<pair<unsigned int,string> > choices;
8026
9696
        
8027
9697
        tmpStr="Local Density";